You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					158 lines
				
				3.9 KiB
			
		
		
			
		
	
	
					158 lines
				
				3.9 KiB
			| 
								 
											7 years ago
										 
									 | 
							
								#define POWER_SAVE_STATUS_DISABLED 0
							 | 
						||
| 
								 | 
							
								//Moving to enabled, but can wakeup not yet enabled
							 | 
						||
| 
								 | 
							
								#define POWER_SAVE_STATUS_SWITCHING 1
							 | 
						||
| 
								 | 
							
								#define POWER_SAVE_STATUS_ENABLED 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								volatile int power_save_status = POWER_SAVE_STATUS_DISABLED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void power_save_enable(void) {
							 | 
						||
| 
								 | 
							
								  power_save_status = POWER_SAVE_STATUS_SWITCHING;
							 | 
						||
| 
								 | 
							
								  puts("Saving power\n");
							 | 
						||
| 
								 | 
							
								  //Turn off can transciever
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN1, 0);
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN2, 0);
							 | 
						||
| 
								 | 
							
								#ifdef PANDA
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN3, 0);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //Turn off GMLAN
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOB, 14, 0);
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOB, 15, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PANDA
							 | 
						||
| 
								 | 
							
								  //Turn off LIN K
							 | 
						||
| 
								 | 
							
								  if (revision == PANDA_REV_C) {
							 | 
						||
| 
								 | 
							
								    set_gpio_output(GPIOB, 7, 0); // REV C
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    set_gpio_output(GPIOB, 4, 0); // REV AB
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // LIN L
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOA, 14, 0);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (is_grey_panda) {
							 | 
						||
| 
								 | 
							
								    char* UBLOX_SLEEP_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
							 | 
						||
| 
								 | 
							
								    int len = 12;
							 | 
						||
| 
								 | 
							
								    uart_ring *ur = get_ring_by_number(1);
							 | 
						||
| 
								 | 
							
								    for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //Setup timer for can enable
							 | 
						||
| 
								 | 
							
								  TIM6->PSC = 48-1; // tick on 1 us
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  TIM6->ARR = 12; // 12us
							 | 
						||
| 
								 | 
							
								  // Enable, One-Pulse Mode, Only overflow interrupt
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
							 | 
						||
| 
								 | 
							
								  TIM6->EGR = TIM_EGR_UG;
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 |= TIM_CR1_CEN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void power_save_enable_can_wake(void) {
							 | 
						||
| 
								 | 
							
								  // CAN Automatic Wake must be done a little while after the sleep
							 | 
						||
| 
								 | 
							
								  // On some cars turning off the can transciver can trigger the wakeup
							 | 
						||
| 
								 | 
							
								  power_save_status = POWER_SAVE_STATUS_ENABLED;
							 | 
						||
| 
								 | 
							
								  puts("Turning can off\n");
							 | 
						||
| 
								 | 
							
								  CAN1->MCR |= CAN_MCR_SLEEP;
							 | 
						||
| 
								 | 
							
								  CAN1->MCR |= CAN_MCR_AWUM;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  CAN2->MCR |= CAN_MCR_SLEEP;
							 | 
						||
| 
								 | 
							
								  CAN2->MCR |= CAN_MCR_AWUM;
							 | 
						||
| 
								 | 
							
								#ifdef PANDA
							 | 
						||
| 
								 | 
							
								  CAN3->MCR |= CAN_MCR_SLEEP;
							 | 
						||
| 
								 | 
							
								  CAN3->MCR |= CAN_MCR_AWUM;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //set timer back
							 | 
						||
| 
								 | 
							
								  TIM6->PSC = 48000-1; // tick on 1 ms
							 | 
						||
| 
								 | 
							
								  TIM6->ARR = 10000; // 10s
							 | 
						||
| 
								 | 
							
								  // Enable, One-Pulse Mode, Only overflow interrupt
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 = TIM_CR1_OPM | TIM_CR1_URS;
							 | 
						||
| 
								 | 
							
								  TIM6->EGR = TIM_EGR_UG;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void power_save_disable(void) {
							 | 
						||
| 
								 | 
							
								  power_save_status = POWER_SAVE_STATUS_DISABLED;
							 | 
						||
| 
								 | 
							
								  puts("not Saving power\n");
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 |= TIM_CR1_CEN; //Restart timer
							 | 
						||
| 
								 | 
							
								  TIM6->CNT = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //Turn on can
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN1, 1);
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN2, 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PANDA
							 | 
						||
| 
								 | 
							
								  set_can_enable(CAN3, 1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //Turn on GMLAN
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOB, 14, 1);
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOB, 15, 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef PANDA
							 | 
						||
| 
								 | 
							
								  //Turn on LIN K
							 | 
						||
| 
								 | 
							
								  if (revision == PANDA_REV_C) {
							 | 
						||
| 
								 | 
							
								    set_gpio_output(GPIOB, 7, 1); // REV C
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    set_gpio_output(GPIOB, 4, 1); // REV AB
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // LIN L
							 | 
						||
| 
								 | 
							
								  set_gpio_output(GPIOA, 14, 1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (is_grey_panda) {
							 | 
						||
| 
								 | 
							
								    char* UBLOX_WAKE_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
							 | 
						||
| 
								 | 
							
								    int len = 12;
							 | 
						||
| 
								 | 
							
								    uart_ring *ur = get_ring_by_number(1);
							 | 
						||
| 
								 | 
							
								    for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //set timer back
							 | 
						||
| 
								 | 
							
								  TIM6->PSC = 48000-1; // tick on 1 ms
							 | 
						||
| 
								 | 
							
								  TIM6->ARR = 10000; // 10s
							 | 
						||
| 
								 | 
							
								  // Enable, One-Pulse Mode, Only overflow interrupt
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
							 | 
						||
| 
								 | 
							
								  TIM6->EGR = TIM_EGR_UG;
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 |= TIM_CR1_CEN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Reset timer when activity
							 | 
						||
| 
								 | 
							
								void power_save_reset_timer() {
							 | 
						||
| 
								 | 
							
								  TIM6->CNT = 0;
							 | 
						||
| 
								 | 
							
								  if (power_save_status != POWER_SAVE_STATUS_DISABLED){
							 | 
						||
| 
								 | 
							
								    power_save_disable();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void power_save_init(void) {
							 | 
						||
| 
								 | 
							
								  puts("Saving power init\n");
							 | 
						||
| 
								 | 
							
								  TIM6->PSC = 48000-1; // tick on 1 ms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  TIM6->ARR = 10000; // 10s
							 | 
						||
| 
								 | 
							
								  // Enable, One-Pulse Mode, Only overflow interrupt
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
							 | 
						||
| 
								 | 
							
								  TIM6->EGR = TIM_EGR_UG;
							 | 
						||
| 
								 | 
							
								  NVIC_EnableIRQ(TIM6_DAC_IRQn);
							 | 
						||
| 
								 | 
							
								  puts("Saving power init done\n");
							 | 
						||
| 
								 | 
							
								  TIM6->DIER = TIM_DIER_UIE;
							 | 
						||
| 
								 | 
							
								  TIM6->CR1 |= TIM_CR1_CEN;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TIM6_DAC_IRQHandler(void) {
							 | 
						||
| 
								 | 
							
								  //Timeout switch to power saving mode.
							 | 
						||
| 
								 | 
							
								  if (TIM6->SR & TIM_SR_UIF) {
							 | 
						||
| 
								 | 
							
								    TIM6->SR = 0;
							 | 
						||
| 
								 | 
							
								#ifdef EON
							 | 
						||
| 
								 | 
							
								    if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
							 | 
						||
| 
								 | 
							
								      power_save_enable();
							 | 
						||
| 
								 | 
							
								    } else if (power_save_status == POWER_SAVE_STATUS_SWITCHING) {
							 | 
						||
| 
								 | 
							
								      power_save_enable_can_wake();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    TIM6->CR1 |= TIM_CR1_CEN;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |