L-line relay (#166)

* Initial version of L-Line Relay

* lline relay fix build, add to health

* Add lline relay to safety

* Lline relay fix build

* Fix tests

* Add lline safety init. Dont fwd with relay closed

* Turn on relay with CAN

* relay hook

* More reliable lline relay

* Longer LLine timeout

* Only turn on wifi if not eon

* Dont disable ESP in early

* Allow CAN to be turned off

 - CAN is turned off via USB.
 - CAN is turned on when either try to transmit or can is received
 - If only transmit is asleep, all messages should send okay
 - If receive is alseep, will miss first message while waking up
 - Sometimes will report error on second message while CAN perif wakes up
 - Saves 130mW!

* Power Saver Mode

 - Gray Panda power consumption 650mw -> 325mW
 - Turns off CAN, GMLAN, LIN, GPS when no activity for 10s
 - No acitvity is no CAN send, CAN Recv, Write to GPS

* Fix power_saving to better turn off can

 - On some cars when the can is turned off, it triggers a wakeup.
 Delaying the automatic wakeup seems to fix this

* Don't save power in pedal

* Fix relay clicking on startup

* Fix duplicate include

* consistent relay setting

* relay_status can be added when needed, as it's started_alt was consumed in other places

* need to skip forwarding only if relay control is claimed

* unneded change

* make lline_relay.h not depending on can.h

* less spaghetti I guess

* less lines

* reset pedal changes

* no unused input

* update version
This commit is contained in:
Nigel Armstrong
2019-04-11 21:03:15 -07:00
committed by rbiasini
parent 11c4cdcc44
commit f8ab74a1cc
21 changed files with 208 additions and 13 deletions

View File

@@ -1 +1 @@
v1.2.0
v1.2.1

View File

@@ -3,6 +3,8 @@
#define ALL_CAN_BUT_MAIN_SILENT 0xFE
#define ALL_CAN_LIVE 0
#include "lline_relay.h"
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
// ********************* instantiate queues *********************
@@ -453,14 +455,16 @@ void can_rx(uint8_t can_number) {
// forwarding (panda only)
#ifdef PANDA
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);
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);
}
}
#endif

View File

@@ -0,0 +1,88 @@
#ifdef PANDA
int relay_control = 0; // True if relay is controlled through l-line
/* Conrol a relay connected to l-line pin */
// 160us cycles, 1 high, 25 low
volatile int turn_on_relay = 0;
volatile int on_cycles = 25;
//5s timeout
#define LLINE_TIMEOUT_CYCLES 31250
volatile int timeout_cycles = LLINE_TIMEOUT_CYCLES;
void TIM5_IRQHandler(void) {
if (TIM5->SR & TIM_SR_UIF) {
on_cycles--;
timeout_cycles--;
if (timeout_cycles == 0) {
turn_on_relay = 0;
}
if (on_cycles > 0) {
if (turn_on_relay) {
set_gpio_output(GPIOC, 10, 0);
}
}
else {
set_gpio_output(GPIOC, 10, 1);
on_cycles = 25;
}
}
TIM5->ARR = 160-1;
TIM5->SR = 0;
}
void lline_relay_init (void) {
set_lline_output(0);
relay_control = 1;
set_gpio_output(GPIOC, 10, 1);
// setup
TIM5->PSC = 48-1; // tick on 1 us
TIM5->CR1 = TIM_CR1_CEN; // enable
TIM5->ARR = 50-1; // 50 us
TIM5->DIER = TIM_DIER_UIE; // update interrupt
TIM5->CNT = 0;
NVIC_EnableIRQ(TIM5_IRQn);
#ifdef DEBUG
puts("INIT LLINE\n");
puts(" SR ");
putui(TIM5->SR);
puts(" PSC ");
putui(TIM5->PSC);
puts(" CR1 ");
putui(TIM5->CR1);
puts(" ARR ");
putui(TIM5->ARR);
puts(" DIER ");
putui(TIM5->DIER);
puts(" SR ");
putui(TIM5->SR);
puts(" CNT ");
putui(TIM5->CNT);
puts("\n");
#endif
}
void lline_relay_release (void) {
set_lline_output(0);
relay_control = 0;
puts("RELEASE LLINE\n");
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
NVIC_DisableIRQ(TIM5_IRQn);
}
void set_lline_output(int to_set) {
timeout_cycles = LLINE_TIMEOUT_CYCLES;
turn_on_relay = to_set;
}
int get_lline_status() {
return turn_on_relay;
}
#endif

View File

@@ -120,6 +120,7 @@ void periph_init() {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
@@ -391,7 +392,9 @@ void gpio_init() {
set_gpio_output(GPIOA, 14, 1);
// C10,C11: L-Line setup on USART 3
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
// LLine now used for relay output
set_gpio_output(GPIOC, 10, 1);
//set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
set_gpio_pullup(GPIOC, 11, PULL_UP);
#endif

View File

@@ -163,6 +163,14 @@ void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {
uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK;
can_send(&to_push, bus_number);
#ifdef PANDA
// Enable relay on can message if allowed.
// Temporary until OP has support for relay
if (safety_relay_hook()) {
set_lline_output(1);
}
#endif
}
}
@@ -444,6 +452,16 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
}
break;
}
// **** 0xf3: set l-line relay
case 0xf3:
{
#ifdef PANDA
if (safety_relay_hook()) {
set_lline_output(setup->b.wValue.w == 1);
}
#endif
break;
}
default:
puts("NO HANDLER ");
puth(setup->b.bRequest);

View File

@@ -29,6 +29,10 @@ int driver_limit_check(int val, int val_last, struct sample_t *val_driver,
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
#ifdef PANDA
float interpolate(struct lookup_t xy, float x);
void lline_relay_init (void);
void lline_relay_release (void);
void set_lline_output(int to_set);
#endif
typedef void (*safety_hook_init)(int16_t param);
@@ -37,6 +41,7 @@ typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send);
typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len);
typedef int (*ign_hook)();
typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd);
typedef int (*relay_hook)();
typedef struct {
safety_hook_init init;
@@ -45,6 +50,7 @@ typedef struct {
tx_hook tx;
tx_lin_hook tx_lin;
fwd_hook fwd;
relay_hook relay;
} safety_hooks;
// This can be set by the safety hooks.
@@ -91,6 +97,10 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return current_hooks->fwd(bus_num, to_fwd);
}
int safety_relay_hook(void) {
return current_hooks->relay();
}
typedef struct {
uint16_t id;
const safety_hooks *hooks;

View File

@@ -115,6 +115,9 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
static void cadillac_init(int16_t param) {
controls_allowed = 0;
cadillac_ign = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int cadillac_ign_hook() {
@@ -128,4 +131,5 @@ const safety_hooks cadillac_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = cadillac_ign_hook,
.fwd = alloutput_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -127,6 +127,9 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
static void chrysler_init(int16_t param) {
chrysler_camera_detected = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
@@ -150,4 +153,5 @@ const safety_hooks chrysler_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = chrysler_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -8,6 +8,9 @@ int default_ign_hook() {
static void nooutput_init(int16_t param) {
controls_allowed = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
@@ -22,6 +25,10 @@ static int nooutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return -1;
}
static int nooutput_relay_hook(int to_set) {
return false;
}
const safety_hooks nooutput_hooks = {
.init = nooutput_init,
.rx = default_rx_hook,
@@ -29,12 +36,16 @@ const safety_hooks nooutput_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = nooutput_fwd_hook,
.relay = nooutput_relay_hook,
};
// *** all output safety mode ***
static void alloutput_init(int16_t param) {
controls_allowed = 1;
#ifdef PANDA
lline_relay_release();
#endif
}
static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
@@ -49,6 +60,10 @@ static int alloutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return -1;
}
static int alloutput_relay_hook(int to_set) {
return true;
}
const safety_hooks alloutput_hooks = {
.init = alloutput_init,
.rx = default_rx_hook,
@@ -56,4 +71,5 @@ const safety_hooks alloutput_hooks = {
.tx_lin = alloutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = alloutput_fwd_hook,
.relay = alloutput_relay_hook,
};

View File

@@ -42,4 +42,5 @@ const safety_hooks elm327_hooks = {
.tx_lin = elm327_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = elm327_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -90,4 +90,5 @@ const safety_hooks ford_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = nooutput_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -228,6 +228,9 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
static void gm_init(int16_t param) {
controls_allowed = 0;
gm_ignition_started = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
static int gm_ign_hook() {
@@ -241,5 +244,5 @@ const safety_hooks gm_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = gm_ign_hook,
.fwd = nooutput_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -48,5 +48,6 @@ const safety_hooks gm_ascm_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = gm_ascm_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -136,6 +136,9 @@ static void honda_init(int16_t param) {
controls_allowed = 0;
bosch_hardware = false;
honda_alt_brake_msg = false;
#ifdef PANDA
lline_relay_release();
#endif
}
static void honda_bosch_init(int16_t param) {
@@ -143,6 +146,9 @@ static void honda_bosch_init(int16_t param) {
bosch_hardware = true;
// Checking for alternate brake override from safety parameter
honda_alt_brake_msg = param == 1 ? true : false;
#ifdef PANDA
lline_relay_release();
#endif
}
static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
@@ -176,6 +182,7 @@ const safety_hooks honda_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = honda_fwd_hook,
.relay = nooutput_relay_hook,
};
const safety_hooks honda_bosch_hooks = {
@@ -185,4 +192,5 @@ const safety_hooks honda_bosch_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = honda_bosch_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -152,6 +152,9 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
static void hyundai_init(int16_t param) {
controls_allowed = 0;
hyundai_giraffe_switch_2 = 0;
#ifdef PANDA
lline_relay_release();
#endif
}
const safety_hooks hyundai_hooks = {
@@ -161,4 +164,5 @@ const safety_hooks hyundai_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = hyundai_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -14,6 +14,11 @@ int subaru_desired_torque_last = 0;
uint32_t subaru_ts_last = 0;
struct sample_t subaru_torque_driver; // last few driver torques measured
static void subaru_init(int16_t param) {
#ifdef PANDA
lline_relay_init();
#endif
}
static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus_number = (to_push->RDTR >> 4) & 0xFF;
@@ -122,10 +127,11 @@ static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
}
const safety_hooks subaru_hooks = {
.init = nooutput_init,
.init = subaru_init,
.rx = subaru_rx_hook,
.tx = subaru_tx_hook,
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = subaru_fwd_hook,
.relay = alloutput_relay_hook,
};

View File

@@ -230,6 +230,9 @@ static void tesla_init(int16_t param)
controls_allowed = 0;
tesla_ignition_started = 0;
gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled
#ifdef PANDA
lline_relay_release();
#endif
}
static int tesla_ign_hook()
@@ -284,4 +287,5 @@ const safety_hooks tesla_hooks = {
.tx_lin = tesla_tx_lin_hook,
.ignition = tesla_ign_hook,
.fwd = tesla_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -160,6 +160,9 @@ static void toyota_init(int16_t param) {
toyota_giraffe_switch_1 = 0;
toyota_camera_forwarded = 0;
toyota_dbc_eps_torque_factor = param;
#ifdef PANDA
lline_relay_release();
#endif
}
static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
@@ -181,6 +184,7 @@ const safety_hooks toyota_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = toyota_fwd_hook,
.relay = nooutput_relay_hook,
};
static void toyota_nolimits_init(int16_t param) {
@@ -189,6 +193,9 @@ static void toyota_nolimits_init(int16_t param) {
toyota_giraffe_switch_1 = 0;
toyota_camera_forwarded = 0;
toyota_dbc_eps_torque_factor = param;
#ifdef PANDA
lline_relay_release();
#endif
}
const safety_hooks toyota_nolimits_hooks = {
@@ -198,4 +205,5 @@ const safety_hooks toyota_nolimits_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = toyota_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -152,5 +152,5 @@ const safety_hooks toyota_ipas_hooks = {
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
.fwd = toyota_fwd_hook,
.relay = nooutput_relay_hook,
};

View File

@@ -392,6 +392,9 @@ class Panda(object):
elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
def set_lline_relay(self, enable):
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, int(enable), 0, b'')
def set_can_loopback(self, enable):
# set can loopback mode for all buses
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')

View File

@@ -246,3 +246,12 @@ void reset_gmlan_switch_timeout(void){
void gmlan_switch_init(int timeout_enable){
}
void lline_relay_init (void) {
}
void lline_relay_release (void) {
}
void set_lline_output(int to_set) {
}