mirror of
https://github.com/infiniteCable2/panda.git
synced 2026-02-18 17:23:52 +08:00
remove k-line driver (#1743)
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
void TIM5_IRQ_Handler(void);
|
||||
|
||||
void setup_timer5(void) {
|
||||
// register interrupt
|
||||
REGISTER_INTERRUPT(TIM5_IRQn, TIM5_IRQ_Handler, 1050000U, FAULT_INTERRUPT_RATE_KLINE_INIT)
|
||||
|
||||
// setup
|
||||
register_set(&(TIM5->PSC), (48-1), 0xFFFFU); // Tick on 1 us
|
||||
register_set(&(TIM5->CR1), TIM_CR1_CEN, 0x3FU); // Enable
|
||||
register_set(&(TIM5->ARR), (5000-1), 0xFFFFFFFFU); // Reset every 5 ms
|
||||
|
||||
// in case it's disabled
|
||||
NVIC_EnableIRQ(TIM5_IRQn);
|
||||
|
||||
// run the interrupt
|
||||
register_set(&(TIM5->DIER), TIM_DIER_UIE, 0x5F5FU); // Update interrupt
|
||||
TIM5->SR = 0;
|
||||
}
|
||||
|
||||
bool k_init = false;
|
||||
bool l_init = false;
|
||||
void setup_kline(bool bitbang) {
|
||||
if (bitbang) {
|
||||
if (k_init) {
|
||||
set_gpio_output(GPIOC, 12, true);
|
||||
}
|
||||
if (l_init) {
|
||||
set_gpio_output(GPIOC, 10, true);
|
||||
}
|
||||
} else {
|
||||
if (k_init) {
|
||||
set_gpio_mode(GPIOC, 12, MODE_ALTERNATE);
|
||||
}
|
||||
if (l_init) {
|
||||
set_gpio_mode(GPIOC, 10, MODE_ALTERNATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_bitbanged_kline(bool marking) {
|
||||
// tickle needs to be super fast (so logic level doesn't change)
|
||||
ENTER_CRITICAL();
|
||||
if (k_init) {
|
||||
register_set_bits(&(GPIOC->ODR), (1U << 12));
|
||||
if (!marking) {
|
||||
register_clear_bits(&(GPIOC->ODR), (1U << 12));
|
||||
}
|
||||
}
|
||||
if (l_init) {
|
||||
register_set_bits(&(GPIOC->ODR), (1U << 10));
|
||||
if (!marking) {
|
||||
register_clear_bits(&(GPIOC->ODR), (1U << 10));
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
// blink blue LED each time line is pulled low
|
||||
current_board->set_led(LED_BLUE, marking);
|
||||
}
|
||||
|
||||
uint16_t kline_data = 0;
|
||||
uint16_t kline_data_len = 0;
|
||||
uint16_t kline_bit_count = 0;
|
||||
uint16_t kline_tick_count = 0;
|
||||
uint16_t kline_ticks_per_bit = 0;
|
||||
|
||||
void TIM5_IRQ_Handler(void) {
|
||||
if ((TIM5->SR & TIM_SR_UIF) && (kline_data != 0U)) {
|
||||
if (kline_bit_count < kline_data_len) {
|
||||
bool marking = (kline_data & (1U << kline_bit_count)) != 0U;
|
||||
set_bitbanged_kline(marking);
|
||||
} else {
|
||||
register_clear_bits(&(TIM5->DIER), TIM_DIER_UIE); // No update interrupt
|
||||
register_set(&(TIM5->CR1), 0U, 0x3FU); // Disable timer
|
||||
setup_kline(false);
|
||||
kline_data = 0U;
|
||||
USB_WritePacket(NULL, 0, 0); // required call (so send nothing)
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
kline_tick_count++;
|
||||
if ((kline_tick_count % kline_ticks_per_bit) == 0U) {
|
||||
kline_bit_count++;
|
||||
}
|
||||
}
|
||||
TIM5->SR = 0;
|
||||
}
|
||||
|
||||
bool bitbang_five_baud_addr(bool k, bool l, uint8_t addr) {
|
||||
bool result = false;
|
||||
if (kline_data == 0U) {
|
||||
k_init = k;
|
||||
l_init = l;
|
||||
kline_data = (addr << 1) + 0x200U; // add start/stop bits
|
||||
kline_data_len = 10U;
|
||||
kline_bit_count = 0;
|
||||
kline_tick_count = 0;
|
||||
kline_ticks_per_bit = 40U; // 200ms == 5bps
|
||||
setup_kline(true);
|
||||
setup_timer5();
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool bitbang_wakeup(bool k, bool l) {
|
||||
bool result = false;
|
||||
if (kline_data == 0U) {
|
||||
k_init = k;
|
||||
l_init = l;
|
||||
kline_data = 2U; // low then high
|
||||
kline_data_len = 2U;
|
||||
kline_bit_count = 0;
|
||||
kline_tick_count = 0;
|
||||
kline_ticks_per_bit = 5U; // 25ms == 40bps
|
||||
setup_kline(true);
|
||||
setup_timer5();
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "drivers/pwm.h"
|
||||
#include "drivers/usb.h"
|
||||
#include "drivers/gmlan_alt.h"
|
||||
#include "drivers/kline_init.h"
|
||||
#include "drivers/simple_watchdog.h"
|
||||
#include "drivers/bootkick.h"
|
||||
|
||||
|
||||
@@ -388,16 +388,6 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
case 0xe7:
|
||||
set_power_save_state(req->param1);
|
||||
break;
|
||||
// **** 0xf0: k-line/l-line wake-up pulse for KWP2000 fast initialization
|
||||
case 0xf0:
|
||||
if(current_board->has_lin) {
|
||||
bool k = (req->param1 == 0U) || (req->param1 == 2U);
|
||||
bool l = (req->param1 == 1U) || (req->param1 == 2U);
|
||||
if (bitbang_wakeup(k, l)) {
|
||||
resp_len = -1; // do not clear NAK yet (wait for bit banging to finish)
|
||||
}
|
||||
}
|
||||
break;
|
||||
// **** 0xf1: Clear CAN ring buffer.
|
||||
case 0xf1:
|
||||
if (req->param1 == 0xFFFFU) {
|
||||
@@ -429,17 +419,6 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
heartbeat_engaged = (req->param1 == 1U);
|
||||
break;
|
||||
}
|
||||
// **** 0xf4: k-line/l-line 5 baud initialization
|
||||
case 0xf4:
|
||||
if(current_board->has_lin) {
|
||||
bool k = (req->param1 == 0U) || (req->param1 == 2U);
|
||||
bool l = (req->param1 == 1U) || (req->param1 == 2U);
|
||||
uint8_t five_baud_addr = (req->param2 & 0xFFU);
|
||||
if (bitbang_five_baud_addr(k, l, five_baud_addr)) {
|
||||
resp_len = -1; // do not clear NAK yet (wait for bit banging to finish)
|
||||
}
|
||||
}
|
||||
break;
|
||||
// **** 0xf6: set siren enabled
|
||||
case 0xf6:
|
||||
siren_enabled = (req->param1 != 0U);
|
||||
|
||||
@@ -879,63 +879,6 @@ class Panda:
|
||||
"""
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf2, port_number, 0, b'')
|
||||
|
||||
# ******************* kline *******************
|
||||
|
||||
# pulse low for wakeup
|
||||
def kline_wakeup(self, k=True, l=True):
|
||||
assert k or l, "must specify k-line, l-line, or both"
|
||||
logging.debug("kline wakeup...")
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf0, 2 if k and l else int(l), 0, b'')
|
||||
logging.debug("kline wakeup done")
|
||||
|
||||
def kline_5baud(self, addr, k=True, l=True):
|
||||
assert k or l, "must specify k-line, l-line, or both"
|
||||
logging.debug("kline 5 baud...")
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, 2 if k and l else int(l), addr, b'')
|
||||
logging.debug("kline 5 baud done")
|
||||
|
||||
def kline_drain(self, bus=2):
|
||||
# drain buffer
|
||||
bret = bytearray()
|
||||
while True:
|
||||
ret = self._handle.controlRead(Panda.REQUEST_IN, 0xe0, bus, 0, 0x40)
|
||||
if len(ret) == 0:
|
||||
break
|
||||
logging.debug(f"kline drain: 0x{ret.hex()}")
|
||||
bret += ret
|
||||
return bytes(bret)
|
||||
|
||||
def kline_ll_recv(self, cnt, bus=2):
|
||||
echo = bytearray()
|
||||
while len(echo) != cnt:
|
||||
ret = self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt - len(echo))
|
||||
if len(ret) > 0:
|
||||
logging.debug(f"kline recv: 0x{ret.hex()}")
|
||||
echo += ret
|
||||
return bytes(echo)
|
||||
|
||||
def kline_send(self, x, bus=2, checksum=True):
|
||||
self.kline_drain(bus=bus)
|
||||
if checksum:
|
||||
x += bytes([sum(x) % 0x100])
|
||||
for i in range(0, len(x), 0xf):
|
||||
ts = x[i:i + 0xf]
|
||||
logging.debug(f"kline send: 0x{ts.hex()}")
|
||||
self._handle.bulkWrite(2, bytes([bus]) + ts)
|
||||
echo = self.kline_ll_recv(len(ts), bus=bus)
|
||||
if echo != ts:
|
||||
logging.error(f"**** ECHO ERROR {i} ****")
|
||||
logging.error(f"0x{echo.hex()}")
|
||||
logging.error(f"0x{ts.hex()}")
|
||||
assert echo == ts
|
||||
|
||||
def kline_recv(self, bus=2, header_len=4):
|
||||
# read header (last byte is length)
|
||||
msg = self.kline_ll_recv(header_len, bus=bus)
|
||||
# read data (add one byte to length for checksum)
|
||||
msg += self.kline_ll_recv(msg[-1]+1, bus=bus)
|
||||
return msg
|
||||
|
||||
def send_heartbeat(self, engaged=True):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, engaged, 0, b'')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user