ELM327: incoming messages cleared before commands to prevent congestion.

master
Jessy Diamond Exum 2017-08-17 02:03:08 -07:00
parent 069f388eed
commit 5ca692e8d3
5 changed files with 64 additions and 29 deletions

View File

@ -53,6 +53,12 @@ int can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
return ret;
}
void can_clear(can_ring *q) {
enter_critical_section();
q->w_ptr = 0;
q->r_ptr = 0;
exit_critical_section();
}
// assign CAN numbering
// bus num: Can bus number on ODB connector. Sent to/from USB
@ -393,4 +399,3 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
void can_set_forwarding(int from, int to) {
can_forwarding[from] = to;
}

View File

@ -126,6 +126,15 @@ int putc(uart_ring *q, char elem) {
return ret;
}
void clear_uart_buff(uart_ring *q) {
enter_critical_section();
q->w_ptr_tx = 0;
q->r_ptr_tx = 0;
q->w_ptr_rx = 0;
q->r_ptr_rx = 0;
exit_critical_section();
}
// ***************************** start UART code *****************************
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_)))
@ -146,7 +155,7 @@ void uart_init(USART_TypeDef *u, int baud) {
// enable uart and tx+rx mode
u->CR1 = USART_CR1_UE;
uart_set_baud(u, baud);
u->CR1 |= USART_CR1_TE | USART_CR1_RE;
//u->CR2 = USART_CR2_STOP_0 | USART_CR2_STOP_1;
//u->CR2 = USART_CR2_STOP_0;
@ -213,4 +222,3 @@ void hexdump(const void *a, int l) {
}
puts("\n");
}

View File

@ -117,12 +117,11 @@ int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) {
// send on serial, first byte to select the ring
void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {
int i;
if (len == 0) return;
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)) {
for (i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
}
}
@ -359,6 +358,26 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
delay(140 * 9000);
break;
// **** 0xf1: Clear CAN ring buffer.
case 0xf1:
if (setup->b.wValue.w == 0xFFFF) {
puts("Clearing CAN Rx queue\n");
can_clear(&can_rx_q);
} else if (setup->b.wValue.w < BUS_MAX) {
puts("Clearing CAN Tx queue\n");
can_clear(can_queues[setup->b.wValue.w]);
}
break;
// **** 0xf2: Clear UART ring buffer.
case 0xf2:
{
uart_ring * rb = get_ring_by_number(setup->b.wValue.w);
if (rb) {
puts("Clearing UART queue.\n");
clear_uart_buff(rb);
}
break;
}
default:
puts("NO HANDLER ");
puth(setup->b.bRequest);

View File

@ -213,6 +213,8 @@ static int ICACHE_FLASH_ATTR panda_usbemu_ctrl_write(uint8_t request_type, uint8
#define panda_set_can0_kbaud(kbps) panda_usbemu_ctrl_write(0x40, 0xde, 0, kbps*10, 0)
#define panda_set_safety_mode(mode) panda_usbemu_ctrl_write(0x40, 0xdc, mode, 0, 0)
#define panda_kline_wakeup_pulse() panda_usbemu_ctrl_write(0x40, 0xf0, 0, 0, 0)
#define panda_clear_can_rx() panda_usbemu_ctrl_write(0x40, 0xf1, 0xFFFF, 0, 0)
#define panda_clear_lin_txrx() panda_usbemu_ctrl_write(0x40, 0xf2, 2, 0, 0)
static int ICACHE_FLASH_ATTR panda_usbemu_can_read(panda_can_msg_t** can_msgs) {
int returned_count = spi_comm((uint8_t *)((const uint16 []){1,0}), 4, pandaRecvData, 0x40);
@ -773,21 +775,12 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd_LINFast(const elm_protocol_t*
return;
}
panda_clear_lin_txrx();
if(!lin_bus_initialized) {
if(!is_auto_detecting)
elm_append_rsp_const("BUS INIT: ");
// Kind of a hack to deal with Panda resending data
// that could not be sent asap. Try to clear it away.
// TODO: A better solution would be to clear out the
// CAN mailboxes on the MCU when the speed changes.
for(int pass = 0; pass < 32; pass++){
int num_can_msgs = panda_usbemu_kline_read(0x40);
if(num_can_msgs < 0) continue;
if(!num_can_msgs) break;
for(int j=0; j<1000; j++) __asm__(""); //Small Delay
}
lin_cmd_backup = cmd;
lin_cmd_backup_len = len;
@ -992,19 +985,6 @@ void ICACHE_FLASH_ATTR elm_ISO15765_timer_cb(void *arg){
static void ICACHE_FLASH_ATTR elm_init_ISO15765(const elm_protocol_t* proto){
panda_set_can0_cbaud(proto->cbaud);
// Kind of a hack to deal with Panda resending data
// that could not be sent asap. Try to clear it away.
// TODO: A better solution would be to clear out the
// CAN mailboxes on the MCU when the speed changes.
for(int pass = 0; pass < 32; pass++){
panda_can_msg_t *can_msgs;
int num_can_msgs = panda_usbemu_can_read(&can_msgs);
if(num_can_msgs < 0) continue;
//if(!num_can_msgs) break;
//os_delay_us(1000);
for(int j=0; j<1000; j++) __asm__(""); //Small Delay
}
}
static void ICACHE_FLASH_ATTR elm_process_obd_cmd_ISO15765(const elm_protocol_t* proto,
@ -1031,6 +1011,8 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd_ISO15765(const elm_protocol_t*
os_printf("\n");
#endif
panda_clear_can_rx();
panda_usbemu_can_write(0, (proto->type==CAN11) ? 0x7DF : 0x18DB33F1,
(uint8_t*)&msg, msg.len+1);

View File

@ -331,6 +331,17 @@ class Panda(object):
print("CAN: BAD RECV, RETRYING")
return parse_can_buffer(dat)
def can_clear(self, bus):
"""Clears all messages from the specified internal CAN ringbuffer as
though it were drained.
Args:
bus (int): can bus number to clear a tx queue, or 0xFFFF to clear the
global can rx queue.
"""
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf1, bus, 0, b'')
# ******************* serial *******************
def serial_read(self, port_number):
@ -345,6 +356,16 @@ class Panda(object):
def serial_write(self, port_number, ln):
return self._handle.bulkWrite(2, struct.pack("B", port_number) + ln)
def serial_clear(self, port_number):
"""Clears all messages (tx and rx) from the specified internal uart
ringbuffer as though it were drained.
Args:
port_number (int): port number of the uart to clear.
"""
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf2, port_number, 0, b'')
# ******************* kline *******************
# pulse low for wakeup