new style power savings
parent
6b282f1c06
commit
6255097a10
|
@ -15,11 +15,7 @@ typedef struct {
|
|||
#define CAN_BUS_RET_FLAG 0x80
|
||||
#define CAN_BUS_NUM_MASK 0x7F
|
||||
|
||||
#ifdef PANDA
|
||||
#define BUS_MAX 4
|
||||
#else
|
||||
#define BUS_MAX 2
|
||||
#endif
|
||||
#define BUS_MAX 4
|
||||
|
||||
extern int can_live, pending_can_live;
|
||||
|
||||
|
@ -54,19 +50,9 @@ int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_S
|
|||
can_buffer(rx_q, 0x1000)
|
||||
can_buffer(tx1_q, 0x100)
|
||||
can_buffer(tx2_q, 0x100)
|
||||
|
||||
#ifdef PANDA
|
||||
can_buffer(tx3_q, 0x100)
|
||||
can_buffer(txgmlan_q, 0x100)
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
|
||||
#else
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q};
|
||||
#endif
|
||||
|
||||
#ifdef PANDA
|
||||
// Forward declare
|
||||
void power_save_reset_timer();
|
||||
#endif
|
||||
can_buffer(tx3_q, 0x100)
|
||||
can_buffer(txgmlan_q, 0x100)
|
||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q};
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
|
||||
|
@ -123,37 +109,21 @@ int can_tx_cnt = 0;
|
|||
int can_txd_cnt = 0;
|
||||
int can_err_cnt = 0;
|
||||
|
||||
// NEO: Bus 1=CAN1 Bus 2=CAN2
|
||||
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
||||
#ifdef PANDA
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
|
||||
uint8_t bus_lookup[] = {0,1,2};
|
||||
uint8_t can_num_lookup[] = {0,1,2,-1};
|
||||
int8_t can_forwarding[] = {-1,-1,-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000, 5000, 333};
|
||||
bool can_autobaud_enabled[] = {false, false, false, false};
|
||||
#define CAN_MAX 3
|
||||
#else
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2};
|
||||
uint8_t bus_lookup[] = {1,0};
|
||||
uint8_t can_num_lookup[] = {1,0};
|
||||
int8_t can_forwarding[] = {-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000};
|
||||
bool can_autobaud_enabled[] = {false, false};
|
||||
#define CAN_MAX 2
|
||||
#endif
|
||||
CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3};
|
||||
uint8_t bus_lookup[] = {0,1,2};
|
||||
uint8_t can_num_lookup[] = {0,1,2,-1};
|
||||
int8_t can_forwarding[] = {-1,-1,-1,-1};
|
||||
uint32_t can_speed[] = {5000, 5000, 5000, 333};
|
||||
bool can_autobaud_enabled[] = {false, false, false, false};
|
||||
#define CAN_MAX 3
|
||||
|
||||
uint32_t can_autobaud_speeds[] = {5000, 2500, 1250, 1000, 10000};
|
||||
#define AUTOBAUD_SPEEDS_LEN (sizeof(can_autobaud_speeds) / sizeof(can_autobaud_speeds[0]))
|
||||
|
||||
#define CANIF_FROM_CAN_NUM(num) (cans[num])
|
||||
#ifdef PANDA
|
||||
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : (CAN==CAN2 ? 1 : 2))
|
||||
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : (CAN==CAN2 ? "CAN2" : "CAN3"))
|
||||
#else
|
||||
#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : 1)
|
||||
#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : "CAN2")
|
||||
#endif
|
||||
#define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num])
|
||||
#define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num])
|
||||
|
||||
|
@ -225,7 +195,6 @@ void can_init_all() {
|
|||
}
|
||||
|
||||
void can_set_gmlan(int bus) {
|
||||
#ifdef PANDA
|
||||
if (bus == -1 || bus != can_num_lookup[3]) {
|
||||
// GMLAN OFF
|
||||
switch (can_num_lookup[3]) {
|
||||
|
@ -265,7 +234,6 @@ void can_set_gmlan(int bus) {
|
|||
can_num_lookup[3] = 2;
|
||||
can_init(2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// CAN error
|
||||
|
@ -302,9 +270,6 @@ void can_sce(CAN_TypeDef *CAN) {
|
|||
set_can_enable(CAN, 1);
|
||||
CAN->MSR &= ~(CAN_MSR_WKUI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
} else {
|
||||
can_err_cnt += 1;
|
||||
|
||||
|
@ -322,9 +287,6 @@ void can_sce(CAN_TypeDef *CAN) {
|
|||
|
||||
void process_can(uint8_t can_number) {
|
||||
if (can_number == 0xff) return;
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
|
||||
enter_critical_section();
|
||||
|
||||
|
@ -390,9 +352,6 @@ void process_can(uint8_t can_number) {
|
|||
// CAN receive handlers
|
||||
// blink blue when we are receiving CAN messages
|
||||
void can_rx(uint8_t can_number) {
|
||||
#ifdef PANDA
|
||||
power_save_reset_timer();
|
||||
#endif
|
||||
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
||||
|
@ -422,25 +381,22 @@ void can_rx(uint8_t can_number) {
|
|||
to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4);
|
||||
|
||||
// forwarding (panda only)
|
||||
#ifdef PANDA
|
||||
if ((get_lline_status() != 0) || !relay_control) { //Relay engaged or relay isn't controlled, allow fwd
|
||||
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
||||
if (bus_fwd_num != -1) {
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
to_send.RIR = to_push.RIR | 1; // TXRQ
|
||||
to_send.RDTR = to_push.RDTR;
|
||||
to_send.RDLR = to_push.RDLR;
|
||||
to_send.RDHR = to_push.RDHR;
|
||||
can_send(&to_send, bus_fwd_num);
|
||||
}
|
||||
// relay engaged or relay isn't controlled, allow fwd
|
||||
if ((get_lline_status() != 0) || !relay_control) {
|
||||
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
||||
if (bus_fwd_num != -1) {
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
to_send.RIR = to_push.RIR | 1; // TXRQ
|
||||
to_send.RDTR = to_push.RDTR;
|
||||
to_send.RDLR = to_push.RDLR;
|
||||
to_send.RDHR = to_push.RDHR;
|
||||
can_send(&to_send, bus_fwd_num);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
safety_rx_hook(&to_push);
|
||||
|
||||
#ifdef PANDA
|
||||
set_led(LED_BLUE, 1);
|
||||
#endif
|
||||
set_led(LED_BLUE, 1);
|
||||
can_push(&can_rx_q, &to_push);
|
||||
|
||||
// next
|
||||
|
@ -472,17 +428,13 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
|
|||
// add CAN packet to send queue
|
||||
// bus number isn't passed through
|
||||
to_push->RDTR &= 0xF;
|
||||
#ifdef PANDA
|
||||
if (bus_number == 3 && can_num_lookup[3] == 0xFF) {
|
||||
// TODO: why uint8 bro? only int8?
|
||||
bitbang_gmlan(to_push);
|
||||
} else {
|
||||
#endif
|
||||
can_push(can_queues[bus_number], to_push);
|
||||
process_can(CAN_NUM_FROM_BUS_NUM(bus_number));
|
||||
#ifdef PANDA
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,10 +84,10 @@ void periph_init() {
|
|||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
|
||||
//RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
|
||||
|
|
28
board/main.c
28
board/main.c
|
@ -1,4 +1,4 @@
|
|||
//#define EON
|
||||
#define EON
|
||||
|
||||
#include "config.h"
|
||||
#include "obj/gitversion.h"
|
||||
|
@ -60,6 +60,10 @@ void debug_ring_callback(uart_ring *ring) {
|
|||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
int is_gpio_started() {
|
||||
return (GPIOA->IDR & (1 << 1)) == 0;
|
||||
}
|
||||
|
||||
int get_health_pkt(void *dat) {
|
||||
struct __attribute__((packed)) {
|
||||
uint32_t voltage;
|
||||
|
@ -87,7 +91,7 @@ int get_health_pkt(void *dat) {
|
|||
int safety_ignition = safety_ignition_hook();
|
||||
if (safety_ignition < 0) {
|
||||
//Use the GPIO pin to determine ignition
|
||||
health->started = (GPIOA->IDR & (1 << 1)) == 0;
|
||||
health->started = is_gpio_started();
|
||||
} else {
|
||||
//Current safety hooks want to determine ignition (ex: GM)
|
||||
health->started = safety_ignition;
|
||||
|
@ -116,7 +120,6 @@ void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {
|
|||
uart_ring *ur = get_ring_by_number(usbdata[0]);
|
||||
if (!ur) return;
|
||||
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
|
||||
if (ur == &esp_ring) power_save_reset_timer();
|
||||
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
|
||||
}
|
||||
}
|
||||
|
@ -545,7 +548,7 @@ int main() {
|
|||
|
||||
#ifdef EON
|
||||
// have to save power
|
||||
power_save_init();
|
||||
power_save_enable();
|
||||
set_esp_mode(ESP_DISABLED);
|
||||
#endif
|
||||
|
||||
|
@ -641,14 +644,27 @@ int main() {
|
|||
for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) {
|
||||
for (int fade = 0; fade < 1024; fade += 8) {
|
||||
for (int i = 0; i < (128/div_mode); i++) {
|
||||
set_led(LED_RED, 0);
|
||||
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
|
||||
set_led(LED_RED, 1);
|
||||
if (fade < 512) { delay(fade); } else { delay(1024-fade); }
|
||||
set_led(LED_RED, 0);
|
||||
if (fade < 512) { delay(512-fade); } else { delay(fade-512); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EON
|
||||
// save power if the car isn't on
|
||||
if (safety_ignition_hook() == -1) {
|
||||
if (is_gpio_started() == 1) {
|
||||
power_save_enable();
|
||||
} else {
|
||||
power_save_disable();
|
||||
}
|
||||
} else {
|
||||
power_save_disable();
|
||||
}
|
||||
#endif
|
||||
|
||||
// turn off the blue LED, turned on by CAN
|
||||
set_led(LED_BLUE, 0);
|
||||
}
|
||||
|
|
|
@ -1,151 +1,55 @@
|
|||
#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
|
||||
#define POWER_SAVE_STATUS_ENABLED 1
|
||||
|
||||
volatile int power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
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
|
||||
if (power_save_status == POWER_SAVE_STATUS_ENABLED) return;
|
||||
|
||||
// turn off can
|
||||
set_can_enable(CAN1, 0);
|
||||
set_can_enable(CAN2, 0);
|
||||
#ifdef PANDA
|
||||
set_can_enable(CAN3, 0);
|
||||
#endif
|
||||
|
||||
//Turn off GMLAN
|
||||
// turn off GMLAN
|
||||
set_gpio_output(GPIOB, 14, 0);
|
||||
set_gpio_output(GPIOB, 15, 0);
|
||||
|
||||
#ifdef PANDA
|
||||
//Turn off LIN K
|
||||
set_gpio_output(GPIOB, 7, 0); // REV C
|
||||
|
||||
// LIN L
|
||||
// turn off LIN
|
||||
set_gpio_output(GPIOB, 7, 0);
|
||||
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]));
|
||||
for (int i = 0; i < sizeof(UBLOX_SLEEP_MSG)-1; 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;
|
||||
if (power_save_status == POWER_SAVE_STATUS_DISABLED) return;
|
||||
|
||||
//Turn on can
|
||||
// turn on can
|
||||
set_can_enable(CAN1, 1);
|
||||
set_can_enable(CAN2, 1);
|
||||
|
||||
#ifdef PANDA
|
||||
set_can_enable(CAN3, 1);
|
||||
#endif
|
||||
|
||||
//Turn on GMLAN
|
||||
// turn on GMLAN
|
||||
set_gpio_output(GPIOB, 14, 1);
|
||||
set_gpio_output(GPIOB, 15, 1);
|
||||
|
||||
#ifdef PANDA
|
||||
//Turn on LIN K
|
||||
set_gpio_output(GPIOB, 7, 1); // REV C
|
||||
|
||||
// LIN L
|
||||
// turn on LIN
|
||||
set_gpio_output(GPIOB, 7, 1);
|
||||
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]));
|
||||
for (int i = 0; i < sizeof(UBLOX_WAKE_MSG)-1; 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;
|
||||
power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue