Untested transition to interrupt-based CAN communication

This commit is contained in:
Ethan Zonca 2016-08-12 17:12:52 -04:00
parent 037e7a9c6d
commit 90be8b3524
8 changed files with 113 additions and 62 deletions

View File

@ -23,8 +23,8 @@ void can_enable(void);
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, uint32_t timeout);
uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout);
uint32_t can_tx(CanTxMsgTypeDef *tx_msg);
//uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout);
uint8_t is_can_msg_pending(uint8_t fifo);
#endif // _CAN_H

View File

@ -6,11 +6,19 @@
#define LED_BLUE_Port GPIOB
#define LED_BLUE LED_BLUE_Port , LED_BLUE_Pin
#define LED_GREEN_Pin GPIO_PIN_1
#define LED_GREEN_Port GPIOB
#define LED_GREEN LED_GREEN_Port , LED_GREEN_Pin
#define LED_DURATION 50
void led_init();
void led_on(void);
void led_blue_blink(uint8_t numblinks);
void led_green_on(void);
void led_green_of(void);
void led_blue_on(void);
void led_process(void);
#endif

View File

@ -46,7 +46,7 @@
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USB_Device init function */
void MX_USB_DEVICE_Init(void);
void usb_init(void);
#ifdef __cplusplus
}

View File

@ -3,13 +3,15 @@
//
#include "stm32f0xx_hal.h"
#include "slcan.h"
#include "usbd_cdc_if.h"
#include "can.h"
#include "led.h"
CAN_HandleTypeDef hcan;
CAN_FilterConfTypeDef filter;
uint32_t prescaler;
static CAN_HandleTypeDef can_handle;
static CAN_FilterConfTypeDef filter;
static uint32_t prescaler;
enum can_bus_state bus_state;
@ -45,7 +47,7 @@ void can_init(void)
// default to 125 kbit/s
prescaler = 48;
hcan.Instance = CAN;
can_handle.Instance = CAN;
bus_state = OFF_BUS;
}
@ -55,21 +57,26 @@ void can_enable(void)
{
if (bus_state == OFF_BUS)
{
hcan.Init.Prescaler = prescaler;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_4TQ;
hcan.Init.BS2 = CAN_BS2_3TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
hcan.pTxMsg = NULL;
HAL_CAN_Init(&hcan);
HAL_CAN_ConfigFilter(&hcan, &filter);
can_handle.Init.Prescaler = prescaler;
can_handle.Init.Mode = CAN_MODE_NORMAL;
can_handle.Init.SJW = CAN_SJW_1TQ;
can_handle.Init.BS1 = CAN_BS1_4TQ;
can_handle.Init.BS2 = CAN_BS2_3TQ;
can_handle.Init.TTCM = DISABLE;
can_handle.Init.ABOM = DISABLE;
can_handle.Init.AWUM = DISABLE;
can_handle.Init.NART = DISABLE;
can_handle.Init.RFLM = DISABLE;
can_handle.Init.TXFP = DISABLE;
can_handle.pTxMsg = NULL;
HAL_CAN_Init(&can_handle);
HAL_CAN_ConfigFilter(&can_handle, &filter);
bus_state = ON_BUS;
HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CEC_CAN_IRQn);
HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0);
}
}
@ -80,8 +87,12 @@ void can_disable(void)
if (bus_state == ON_BUS)
{
// do a bxCAN reset (set RESET bit to 1)
hcan.Instance->MCR |= CAN_MCR_RESET;
can_handle.Instance->MCR |= CAN_MCR_RESET;
bus_state = OFF_BUS;
HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
HAL_CAN_DeInit(&can_handle);
}
HAL_GPIO_WritePin(LED_BLUE, GPIO_PIN_RESET);
}
@ -139,38 +150,48 @@ void can_set_silent(uint8_t silent)
}
if (silent)
{
hcan.Init.Mode = CAN_MODE_SILENT;
can_handle.Init.Mode = CAN_MODE_SILENT;
} else {
hcan.Init.Mode = CAN_MODE_NORMAL;
can_handle.Init.Mode = CAN_MODE_NORMAL;
}
}
// Send a message on the CAN bus (blocking)
uint32_t can_tx(CanTxMsgTypeDef *tx_msg, uint32_t timeout)
uint32_t can_tx(CanTxMsgTypeDef *tx_msg)
{
uint32_t status;
// transmit can frame
hcan.pTxMsg = tx_msg;
status = HAL_CAN_Transmit(&hcan, timeout);
can_handle.pTxMsg = tx_msg;
status = HAL_CAN_Transmit_IT(&can_handle);
led_on();
led_blue_on();
return status;
}
// Receive a message from the CAN bus (blocking)
uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout)
// CAN rxcomplete callback TODO: Move to interrupts?
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef *hcan)
{
uint32_t status;
led_blue_on();
hcan.pRxMsg = rx_msg;
// 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);
status = HAL_CAN_Receive(&hcan, CAN_FIFO0, timeout);
HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0);
}
led_on();
return status;
void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef *hcan)
{
}
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
{
//error_assert(ERR_CANBUS);
}
@ -181,5 +202,12 @@ uint8_t is_can_msg_pending(uint8_t fifo)
{
return 0;
}
return (__HAL_CAN_MSG_PENDING(&hcan, fifo) > 0);
return (__HAL_CAN_MSG_PENDING(&can_handle, fifo) > 0);
}
// Return reference to CAN handle
CAN_HandleTypeDef* can_gethandle(void)
{
return &can_handle;
}

View File

@ -23,3 +23,9 @@ void SysTick_Handler(void)
HAL_SYSTICK_IRQHandler();
}
// Handle CAN interrupts
void CEC_CAN_IRQHandler(void)
{
HAL_CAN_IRQHandler(can_gethandle());
}

View File

@ -23,8 +23,35 @@ void led_init()
}
// Turn green LED on
void led_green_on(void)
{
HAL_GPIO_WritePin(LED_GREEN, 1);
}
// Turn green LED on
void led_green_off(void)
{
HAL_GPIO_WritePin(LED_GREEN, 0);
}
// Blink blue LED (blocking)
void led_blue_blink(uint8_t numblinks)
{
uint8_t i;
for(i=0; i<numblinks; i++)
{
HAL_GPIO_WritePin(LED_BLUE, 1);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_BLUE, 0);
HAL_Delay(100);
}
}
// Attempt to turn on status LED
void led_on(void)
void led_blue_on(void)
{
// Make sure the LED has been off for at least LED_DURATION before turning on again
// This prevents a solid status LED on a busy canbus

View File

@ -5,7 +5,6 @@
#include "stm32f0xx_hal.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
#include "can.h"
#include "slcan.h"
#include "system.h"
@ -15,34 +14,17 @@
int main(void)
{
HAL_Init();
system_init();
can_init();
led_init();
MX_USB_DEVICE_Init();
usb_init();
// turn on green LED
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
// blink red LED for test
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
CanRxMsgTypeDef rx_msg;
uint8_t msg_buf[SLCAN_MTU];
led_green_on();
led_blue_blink(3);
while(1)
{
if(is_can_msg_pending(CAN_FIFO0) && can_rx(&rx_msg, 2) == HAL_OK)
{
uint32_t numbytes = slcan_parse_frame(msg_buf, &rx_msg);
CDC_Transmit_FS(msg_buf, numbytes);
}
led_process();
}
}

View File

@ -45,7 +45,7 @@
USBD_HandleTypeDef hUsbDeviceFS;
/* init function */
void MX_USB_DEVICE_Init(void)
void usb_init(void)
{
/* Init Device Library,Add Supported Class and Start the library*/
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);