diff --git a/inc/can.h b/inc/can.h --- a/inc/can.h +++ b/inc/can.h @@ -11,7 +11,7 @@ extern CAN_HandleTypeDef can_handle; -void can_init(void); +void can_init(uint32_t rx_id, uint32_t broadcast_id); void can_send_test(uint16_t id); bool can_send(uint32_t id, uint32_t ide, uint8_t dlc, uint8_t data[8]); void can_set_receive_mask(uint32_t mask); diff --git a/inc/flash.h b/inc/flash.h new file mode 100644 --- /dev/null +++ b/inc/flash.h @@ -0,0 +1,27 @@ +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#include "stm32f0xx_hal.h" +#include "stm32f0xx_hal_flash.h" +#include "config.h" + +#define PAGE_SIZE ((uint16_t)0x400) +#define END_ADDR 0x08007FFF + +typedef union +{ + struct { + uint32_t can_id; + uint16_t data_rate; + uint8_t led_brightness; + } val; + + uint16_t data[128]; +} flash_settings_t; + +void flash_save(flash_settings_t* tosave); +void flash_restore(flash_settings_t* tosave); +void flash_load_defaults(flash_settings_t* torestore); +void flash_erase(void); + +#endif /* _FLASH_H_ */ diff --git a/inc/protocol.h b/inc/protocol.h --- a/inc/protocol.h +++ b/inc/protocol.h @@ -5,6 +5,9 @@ #include "config.h" #include "can.h" +#include "flash.h" + +#define DEFAULT_BROADCAST_ID 0x00000000 typedef struct { bool command; @@ -12,8 +15,8 @@ typedef struct { uint16_t key; uint8_t sensor; union { - float float_data; - uint8_t byte_data[4]; + float float_data; + uint8_t byte_data[4]; } data; } protocol_message_t; @@ -27,6 +30,14 @@ typedef enum { } protocol_command_t; typedef enum { + MASTER = 0x00, + AIRSENSE = 0x01, + RELAYDRIVE = 0X02, + WATERSENSE = 0x03, + PROTOMODULE = 0x04, +} protocol_device_t; + +typedef enum { NONE = 0x0000, DIGITAL_INPUT = 0x0001, FREQ_INPUT = 0x0002, @@ -48,10 +59,12 @@ typedef enum { LED_BRIGHTNESS = 0x0103, } protocol_data_key_t; - +void protocol_init(protocol_device_t device); bool protocol_receive_message(CanRxMsgTypeDef* can_message); bool protocol_send_message(protocol_message_t* message); bool protocol_process_message(protocol_message_t* message); +bool protocol_send_data(protocol_data_key_t key, uint8_t sensor, float data); +bool protocol_send_test(); __weak bool protocol_estop(bool value); __weak bool protocol_set_output(protocol_message_t* message); diff --git a/src/can.c b/src/can.c --- a/src/can.c +++ b/src/can.c @@ -7,8 +7,10 @@ CanRxMsgTypeDef can_rx_msg; CanTxMsgTypeDef can_tx_msg; bool can_silenced; +uint32_t can_broadcast_id; +uint32_t can_rx_id; -void can_init(void) +void can_init(uint32_t rx_id, uint32_t broadcast_id) { can_handle.Instance = CAN; can_handle.pRxMsg = &can_rx_msg; @@ -46,6 +48,8 @@ void can_init(void) HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); can_silenced = false; + can_rx_id = rx_id; + can_broadcast_id = broadcast_id; } void can_send_test(uint16_t id) @@ -118,9 +122,12 @@ bool can_silence_bus(bool value) void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) { - protocol_receive_message(hcan->pRxMsg); - led_start_time(LED_CAN, 500); - HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); + if ((hcan->pRxMsg->StdId == can_rx_id) | (hcan->pRxMsg->StdId == can_broadcast_id)) + { + protocol_receive_message(hcan->pRxMsg); + led_start_time(LED_CAN, 500); + HAL_CAN_Receive_IT(&can_handle, CAN_FIFO0); + } } void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan) {} diff --git a/src/flash.c b/src/flash.c new file mode 100644 --- /dev/null +++ b/src/flash.c @@ -0,0 +1,67 @@ +#include "flash.h" + +__attribute__((__section__(".eeprom"))) uint16_t eeprom[512]; + +#define MAGIC_NUMBER 0x0BAE + +static void __flash_write(flash_settings_t* tosave); + +void flash_save(flash_settings_t* tosave) +{ + __flash_write(tosave); +} + +void flash_restore(flash_settings_t* torestore) +{ + //read flash and calculate checksum + uint16_t checksum = MAGIC_NUMBER; + uint16_t i; + for(i = 0; i < (sizeof(flash_settings_t)/2); i++) + { + torestore->data[i] = eeprom[i]; + checksum ^= torestore->data[i]; + } + + //if checksum doesn't match, load default settings + if((checksum ^ eeprom[i+1]) != 0) { + flash_load_defaults(torestore); + } +} + +void flash_load_defaults(flash_settings_t* torestore) +{ + + torestore->val.can_id = DEFAULT_CAN_ID; + torestore->val.data_rate = DEFAULT_DATA_RATE; + torestore->val.led_brightness = DEFAULT_LED_BRIGHTNESS; + +} + +static void __flash_write(flash_settings_t* tosave) +{ + // Erase mem + HAL_FLASH_Unlock(); + + // Erase the FLASH pages + FLASH_EraseInitTypeDef erase; + erase.TypeErase = TYPEERASE_PAGES; + erase.PageAddress = (uint32_t) eeprom; + erase.NbPages = 1; + uint32_t SectorError = 0; + HAL_FLASHEx_Erase(&erase, &SectorError); + CLEAR_BIT(FLASH->CR, FLASH_CR_PER); + + // write to flash and calculate the checksum + uint16_t checksum = MAGIC_NUMBER; + uint16_t i; + for(i = 0; i < (sizeof(flash_settings_t)/2); i++) + { + HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)&eeprom[i], tosave->data[i]); + checksum ^= tosave->data[i]; + } + + // write the checksum + HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)&eeprom[i+1], checksum); + + HAL_FLASH_Lock(); +} diff --git a/src/protocol.c b/src/protocol.c --- a/src/protocol.c +++ b/src/protocol.c @@ -1,5 +1,22 @@ #include "protocol.h" +protocol_device_t protocol_device; +flash_settings_t protocol_settings; + +void protocol_init(protocol_device_t device) +{ + protocol_device = device; + flash_restore(&protocol_settings); + + can_init(protocol_settings.val.can_id, DEFAULT_BROADCAST_ID); +} + +bool protocol_send_test() +{ + bool result = true; + can_send_test(protocol_settings.val.can_id | 0x00000001); + return result; +} bool protocol_receive_message(CanRxMsgTypeDef* can_message) { @@ -34,7 +51,7 @@ bool protocol_send_message(protocol_mess data[6] = (message->data.byte_data[2] >> 8) & 0xFF; data[7] = (message->data.byte_data[3] >> 0) & 0xFF; - can_send(CAN_SEND_ID, CAN_ID_STD, 8, data); + can_send(protocol_settings.val.can_id | 0x00000001, CAN_ID_STD, 8, data); return result; } @@ -83,6 +100,22 @@ bool protocol_process_message(protocol_m return result; } +bool protocol_send_data(protocol_data_key_t key, uint8_t sensor, float data) +{ + bool result = true; + + protocol_message_t message; + message.command = false; + message.id = protocol_device; + message.key = key; + message.sensor = sensor; + message.data.float_data = data; + + result = protocol_send_message(&message); + + return result; +} + __weak bool protocol_estop(bool value) { return false;