# HG changeset patch # User matthewreed # Date 2017-07-02 20:26:42 # Node ID a72d393244e6cddd889f6315e972592ea3853d7b # Parent 021012fc2f310b2574f012b59bef0c9e3198ddbb Added can buffering and protocol updates diff --git a/inc/can.h b/inc/can.h --- a/inc/can.h +++ b/inc/can.h @@ -8,6 +8,7 @@ #include "config.h" #include "led.h" #include "protocol.h" +#include "can_buffer.h" extern CAN_HandleTypeDef can_handle; @@ -17,5 +18,7 @@ bool can_send(uint32_t id, uint32_t ide, void can_set_receive_mask(uint32_t mask); void can_set_receive_id(uint32_t id); bool can_silence_bus(bool value); +void can_receive(void); +void can_process_receive_buffer(void); #endif //_CAN_H_ diff --git a/inc/can_buffer.h b/inc/can_buffer.h new file mode 100644 --- /dev/null +++ b/inc/can_buffer.h @@ -0,0 +1,25 @@ +#ifndef _CAN_BUFFER_H +#define _CAN_BUFFER_H + +#include +#include "system.h" + +#define CAN_BUFFER_SIZE 8 + +typedef enum CanBufferStatus {CAN_BUFFER_OK, CAN_BUFFER_EMPTY, CAN_BUFFER_FULL} CanBufferStatus; + +typedef struct CanBuffer +{ + volatile CanRxMsgTypeDef data[CAN_BUFFER_SIZE]; + volatile uint8_t head; + volatile uint8_t tail; + volatile uint8_t count; +} CanBuffer; + +void can_buffer_init(volatile CanBuffer *buffer); +CanBufferStatus can_buffer_add(volatile CanBuffer *buffer, CanRxMsgTypeDef *msg); +volatile CanRxMsgTypeDef* can_buffer_remove(volatile CanBuffer *buffer); +bool can_buffer_is_empty(volatile CanBuffer *buffer); +uint8_t can_buffer_size(volatile CanBuffer *buffer); + +#endif //_CAN_BUFFER_H diff --git a/inc/protocol.h b/inc/protocol.h --- a/inc/protocol.h +++ b/inc/protocol.h @@ -43,7 +43,7 @@ typedef enum { FREQ_INPUT = 0x0002, ANALOG_INPUT = 0x0003, DIGITAL_OUTPUT = 0x0004, - FREQ_OUTPUT = 0x0005, + PWM_OUTPUT = 0x0005, ANALOG_OUTPUT = 0x0006, AIR_TEMP = 0x0007, AIR_HUMIDITY = 0x0008, diff --git a/src/can.c b/src/can.c --- a/src/can.c +++ b/src/can.c @@ -10,6 +10,8 @@ bool can_silenced; uint32_t can_broadcast_id; uint32_t can_rx_id; +volatile CanBuffer can_rx_buffer; + void can_init(uint32_t rx_id, uint32_t broadcast_id) { can_handle.Instance = CAN; @@ -43,13 +45,15 @@ void can_init(uint32_t rx_id, uint32_t b can_filter.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(&can_handle, &can_filter); - HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0); - HAL_NVIC_EnableIRQ(CEC_CAN_IRQn); - HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); + //HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0); + //HAL_NVIC_EnableIRQ(CEC_CAN_IRQn); + //HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); can_silenced = false; can_rx_id = rx_id; can_broadcast_id = broadcast_id; + + can_buffer_init(&can_rx_buffer); } void can_send_test(uint16_t id) @@ -120,14 +124,42 @@ bool can_silence_bus(bool value) return result; } +void can_receive(void) +{ + if ((can_handle.Instance->RF0R & CAN_RF0R_FMP0) != 0) + { + HAL_StatusTypeDef status = HAL_CAN_Receive(&can_handle, 0, 0); + + if ((status == HAL_OK) & ((can_handle.pRxMsg->StdId == can_rx_id) | (can_handle.pRxMsg->StdId == can_broadcast_id))) + { + can_buffer_add(&can_rx_buffer, can_handle.pRxMsg); + } + //can_handle.Instance->RF0R |= CAN_RF0R_RFOM0; + + led_blink_once(LED_CAN, 250); + } +} + +void can_process_receive_buffer(void) +{ + CanRxMsgTypeDef msg; + uint8_t size = can_buffer_size(&can_rx_buffer); + + for (uint8_t i = 0; i < size; i++) + { + msg = *can_buffer_remove(&can_rx_buffer); + protocol_receive_message(&msg); + } +} + void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) { if ((hcan->pRxMsg->StdId == can_rx_id) | (hcan->pRxMsg->StdId == can_broadcast_id)) { - protocol_receive_message(hcan->pRxMsg); + can_buffer_add(&can_rx_buffer, hcan->pRxMsg); } - led_blink_once(LED_CAN, 500); + led_blink_once(LED_ERROR, 500); HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); } diff --git a/src/can_buffer.c b/src/can_buffer.c new file mode 100644 --- /dev/null +++ b/src/can_buffer.c @@ -0,0 +1,40 @@ +#include "can_buffer.h" + +void can_buffer_init(volatile CanBuffer *buffer) +{ + memset((void*)buffer, 0, sizeof(CanBuffer)); +} + +CanBufferStatus can_buffer_add(volatile CanBuffer *buffer, CanRxMsgTypeDef *msg) +{ + if ((uint16_t) buffer->count < ((uint16_t) CAN_BUFFER_SIZE)) { + buffer->data[buffer->head] = *msg; + buffer->head = (buffer->head + 1) % CAN_BUFFER_SIZE; + buffer->count++; + return CAN_BUFFER_OK; + } + else { + return CAN_BUFFER_FULL; + } +} + +volatile CanRxMsgTypeDef* can_buffer_remove(volatile CanBuffer *buffer) +{ + volatile CanRxMsgTypeDef* msg; + if (buffer->count > 0) { + msg = &buffer->data[buffer->tail]; + buffer->tail = (buffer->tail + 1) % CAN_BUFFER_SIZE; + buffer->count--; + } + return msg; +} + +bool can_buffer_is_empty(volatile CanBuffer *buffer) +{ + return (buffer->count < 1); +} + +uint8_t can_buffer_size(volatile CanBuffer *buffer) +{ + return buffer->count; +} diff --git a/src/protocol.c b/src/protocol.c --- a/src/protocol.c +++ b/src/protocol.c @@ -7,6 +7,7 @@ void protocol_init(protocol_device_t dev { protocol_device = device; flash_restore(&protocol_settings); + led_set_brightness(protocol_settings.val.led_brightness); can_init(protocol_settings.val.can_id, DEFAULT_BROADCAST_ID); } @@ -127,16 +128,24 @@ bool _protocol_config(protocol_message_t { bool result = false; - if (message->key == LED_BRIGHTNESS) + if (message->key == CAN_ID) + { + uint32_t can_id = (uint16_t) message->data.float_data; + protocol_settings.val.can_id = can_id; + flash_save(&protocol_settings); + } + else if (message->key == DATA_RATE) + { + uint16_t data_rate = (uint16_t) message->data.float_data; + protocol_settings.val.data_rate = data_rate * 1000; + flash_save(&protocol_settings); + } + else if (message->key == LED_BRIGHTNESS) { uint8_t brightness = (uint8_t)message->data.float_data; result = led_set_brightness(brightness); protocol_settings.val.led_brightness = brightness; - } - else if (message->key == DATA_RATE) - { - uint16_t data_rate = (uint16_t) message->data.float_data; - protocol_settings.val.data_rate = data_rate; + flash_save(&protocol_settings); } else {