mirror of
https://github.com/infiniteCable2/panda.git
synced 2026-02-18 17:23:52 +08:00
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:
committed by
rbiasini
parent
11c4cdcc44
commit
f8ab74a1cc
@@ -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
|
||||
|
||||
|
||||
88
board/drivers/lline_relay.h
Normal file
88
board/drivers/lline_relay.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
18
board/main.c
18
board/main.c
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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'')
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user