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_bitrate(enum can_bitrate bitrate);
|
||||||
void can_set_silent(uint8_t silent);
|
void can_set_silent(uint8_t silent);
|
||||||
uint32_t can_tx(CanTxMsgTypeDef *tx_msg);
|
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);
|
uint8_t is_can_msg_pending(uint8_t fifo);
|
||||||
CAN_HandleTypeDef* can_gethandle(void);
|
CAN_HandleTypeDef* can_gethandle(void);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
/* Exported cariables --------------------------------------------------------*/
|
/* Exported cariables --------------------------------------------------------*/
|
||||||
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
||||||
|
|
||||||
|
void usb_process(void);
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
/* Exported functions ------------------------------------------------------- */
|
/* Exported functions ------------------------------------------------------- */
|
||||||
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype
|
/** @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;
|
static uint32_t prescaler;
|
||||||
enum can_bus_state bus_state;
|
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 CanRxMsgTypeDef can_rx_msg;
|
||||||
static CanTxMsgTypeDef can_tx_msg;
|
static CanTxMsgTypeDef can_tx_msg;
|
||||||
|
|
||||||
|
@ -178,17 +181,41 @@ uint32_t can_tx(CanTxMsgTypeDef *tx_msg)
|
||||||
return status;
|
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?
|
// CAN rxcomplete callback TODO: Move to interrupts?
|
||||||
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
|
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
|
||||||
{
|
{
|
||||||
led_blue_on();
|
led_blue_on();
|
||||||
|
process_recv = 1;
|
||||||
// // 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);
|
|
||||||
|
|
||||||
HAL_CAN_Receive_IT(hcan, CAN_FIFO0);
|
HAL_CAN_Receive_IT(hcan, CAN_FIFO0);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "stm32f0xx_hal.h"
|
#include "stm32f0xx_hal.h"
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
|
#include "usbd_cdc_if.h"
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
#include "slcan.h"
|
#include "slcan.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
@ -26,6 +27,8 @@ int main(void)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
led_process();
|
led_process();
|
||||||
|
can_process();
|
||||||
|
usb_process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ int8_t slcan_parse_str(uint8_t *buf, uint8_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the message
|
// send the message
|
||||||
can_tx(&frame);
|
can_preptx(&frame);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,7 @@ static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
|
||||||
*
|
*
|
||||||
* @note
|
* @note
|
||||||
* This function will block any OUT packet reception on USB endpoint
|
* 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
|
* is complete on CDC interface (ie. using DMA controller) it will result
|
||||||
* in receiving more data while previous ones are still not sent.
|
* 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[SLCAN_MTU];
|
||||||
uint8_t slcan_str_index = 0;
|
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)
|
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 7 */
|
|
||||||
uint8_t n = *Len;
|
uint8_t n = *Len;
|
||||||
uint8_t i;
|
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++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (Buf[i] == '\r') {
|
if (Buf[i] == '\r') {
|
||||||
slcan_parse_str(slcan_str, slcan_str_index);
|
// slcan_parse_str(slcan_str, slcan_str_index);
|
||||||
slcan_str_index = 0;
|
packet_ready = 1;
|
||||||
} else {
|
// slcan_str_index = 0;
|
||||||
slcan_str[slcan_str_index++] = Buf[i];
|
} else {
|
||||||
}
|
slcan_str[slcan_str_index++] = Buf[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare for next read
|
// 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);
|
USBD_CDC_ReceivePacket(hUsbDevice_0);
|
||||||
|
|
||||||
return (USBD_OK);
|
return (USBD_OK);
|
||||||
/* USER CODE END 7 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue