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:
parent
2c5f345955
commit
ff1036f57b
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
41
src/can.c
41
src/can.c
|
@ -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);
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue