Defer some work to the main loop. Deferring slcan parse from usbd_cdc_if receive interrupt fixes freezing but CANables stop talking.

This commit is contained in:
Ethan Zonca 2016-08-16 22:15:20 -04:00
parent 2c5f345955
commit ff1036f57b
6 changed files with 76 additions and 17 deletions

View File

@ -24,6 +24,10 @@ void can_disable(void);
void can_set_bitrate(enum can_bitrate bitrate);
void can_set_silent(uint8_t silent);
uint32_t can_tx(CanTxMsgTypeDef *tx_msg);
void can_process(void);
void can_preptx(CanTxMsgTypeDef *tx_msg);
uint8_t is_can_msg_pending(uint8_t fifo);
CAN_HandleTypeDef* can_gethandle(void);

View File

@ -45,6 +45,7 @@
/* Exported cariables --------------------------------------------------------*/
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
void usb_process(void);
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype

View File

@ -14,6 +14,9 @@ static CAN_FilterConfTypeDef filter;
static uint32_t prescaler;
enum can_bus_state bus_state;
static volatile uint8_t process_recv = 0;
static volatile uint8_t process_tx = 0;
static CanRxMsgTypeDef can_rx_msg;
static CanTxMsgTypeDef can_tx_msg;
@ -178,17 +181,41 @@ uint32_t can_tx(CanTxMsgTypeDef *tx_msg)
return status;
}
CanTxMsgTypeDef localmsg;
void can_process(void)
{
if(process_recv)
{
CanRxMsgTypeDef* rxmsg = can_handle.pRxMsg;
uint8_t msg_buf[SLCAN_MTU];
uint32_t numbytes = slcan_parse_frame(msg_buf, rxmsg);
CDC_Transmit_FS(msg_buf, numbytes);
process_recv = 0;
}
if(process_tx)
{
can_tx(&localmsg);
process_tx = 0;
}
}
void can_preptx(CanTxMsgTypeDef *msg)
{
localmsg = *msg;
process_tx = 1;
}
// CAN rxcomplete callback TODO: Move to interrupts?
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
led_blue_on();
// // TODO: Store this message in a buffer and defer CDC send to main loop
CanRxMsgTypeDef* rxmsg = hcan->pRxMsg;
uint8_t msg_buf[SLCAN_MTU];
uint32_t numbytes = slcan_parse_frame(msg_buf, rxmsg);
CDC_Transmit_FS(msg_buf, numbytes);
process_recv = 1;
HAL_CAN_Receive_IT(hcan, CAN_FIFO0);
}
/*

View File

@ -5,6 +5,7 @@
#include "stm32f0xx_hal.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
#include "can.h"
#include "slcan.h"
#include "system.h"
@ -26,6 +27,8 @@ int main(void)
while(1)
{
led_process();
can_process();
usb_process();
}
}

View File

@ -208,7 +208,7 @@ int8_t slcan_parse_str(uint8_t *buf, uint8_t len)
}
// send the message
can_tx(&frame);
can_preptx(&frame);
return 0;
}

View File

@ -235,7 +235,7 @@ static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
*
* @note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* until exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
@ -247,18 +247,43 @@ static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
uint8_t slcan_str[SLCAN_MTU];
uint8_t slcan_str_index = 0;
static volatile uint8_t packet_ready = 0;
static volatile uint8_t packetbuf[256];
// Process reccvd packet
void usb_process(void)
{
if(packet_ready)
{
slcan_parse_str(slcan_str, slcan_str_index);
packet_ready = 0;
slcan_str_index = 0;
}
}
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 7 */
uint8_t n = *Len;
uint8_t i;
// TODO: Rewrite all of this with a FIFO! This is bad.
// hard max at MTU
if(n>30)
{
n = 30;
}
for (i = 0; i < n; i++) {
if (Buf[i] == '\r') {
slcan_parse_str(slcan_str, slcan_str_index);
slcan_str_index = 0;
} else {
slcan_str[slcan_str_index++] = Buf[i];
}
if (Buf[i] == '\r') {
// slcan_parse_str(slcan_str, slcan_str_index);
packet_ready = 1;
// slcan_str_index = 0;
} else {
slcan_str[slcan_str_index++] = Buf[i];
}
}
// prepare for next read
@ -266,7 +291,6 @@ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
USBD_CDC_ReceivePacket(hUsbDevice_0);
return (USBD_OK);
/* USER CODE END 7 */
}
/**