diff --git a/generator/bus.py b/generator/bus.py index dfa0fbd..8be89ce 100644 --- a/generator/bus.py +++ b/generator/bus.py @@ -20,7 +20,7 @@ def write(can, computers, output_path=bus_path): raw_buses = set() for computer in computers: if not ('can' in computer.participation['name'].keys()): - # This computer neither sends nor recieves can messages + # This computer neither sends nor receives can messages continue raw_buses |= set(computer.participation['name']['can'].mapping.values()) diff --git a/generator/computers_c.py b/generator/computers_c.py index 0c40b4d..4fca355 100644 --- a/generator/computers_c.py +++ b/generator/computers_c.py @@ -6,12 +6,14 @@ frame_handler, is_multplxd from math import ceil +raw_bus_to_handle = {"CAN_1": "hcan1", "CAN_2": "hcan2", "CAN_3": "hcan3"} +raw_bus_to_instance = {"CAN_1": "CAN1", "CAN_2": "CAN2", "CAN_3": "CAN3"} def single_handler(frame, name_prepends, num_tabs, fw): tot_name = coord(name_prepends, frame.name, prefix=False) fw( '\t' * num_tabs + 'case CANlib_{}_key:'.format(tot_name) + '\n' + - '\t' * (num_tabs + 1) + 'CANlib_Handle_{}(frame);\n'.format(tot_name) + + '\t' * (num_tabs + 1) + 'CANlib_Handle_{}(ts_frame);\n'.format(tot_name) + '\t' * (num_tabs + 1) + 'break;\n' ) @@ -63,9 +65,16 @@ def write(can, computers, output_path=computer_c_dir_path): with open(f_path, 'w') as f: fw = f.write + fw('#include \n') + fw('#include \n') + fw('#include \n') fw('#include "pack_unpack.h"\n') fw('#include "canlib_{}.h"\n\n'.format(computer.name)) + fw('extern CAN_HandleTypeDef hcan1;\n') + fw('extern CAN_HandleTypeDef hcan2;\n') + fw('extern CAN_HandleTypeDef hcan3;\n\n') + fw( 'CAN_Raw_Bus_T CANlib_GetRawBus(CANlib_Bus_T bus) {\n' '\tswitch (bus) {\n' @@ -91,10 +100,11 @@ def write(can, computers, output_path=computer_c_dir_path): fw('\t}\n}\n\n') for busnm, bus in computer.participation['name']['can'].subscribe.items(): - fw('static void CANlib_HandleFrame_{}(Frame* frame)'.format(busnm) + '{\n') + + fw('static void CANlib_HandleFrame_{}(TimestampedFrame* ts_frame)'.format(busnm) + '{\n') if any(is_multplxd(msg) for msg in bus): fw('\tuint64_t bitstring;\n') - fw('\tswitch(frame->id) {\n') + fw('\tswitch(ts_frame->frame.id) {\n') for msg in bus: msg_handler(msg, busnm, fw) @@ -108,27 +118,42 @@ def write(can, computers, output_path=computer_c_dir_path): for busnm, bus in computer.participation['name']['can'].subscribe.items(): fw( - 'static void CANlib_update_can_{}(void)'.format(busnm) + '{\n' + - '\tFrame frame;\n' + 'static void CANlib_Update_can_{}(void)'.format(busnm) + ' {\n' + + '\tTimestampedFrame ts_frame;\n' ) + + raw_bus = computer.participation['name']['can'].mapping[busnm] + instance = raw_bus_to_handle[raw_bus] + fw( - '\tCANlib_ReadFrame(&frame, {});\n'.format(busnm) + - '\tCANlib_HandleFrame_{}(&frame);\n'.format(busnm) + + '\tif (HAL_CANlib_ReadFrame(&{}, &(ts_frame.frame))) {{\n'.format(instance) + + '\t\tts_frame.stamp = HAL_GetTick();\n' + + '\t\tCANlib_HandleFrame_{}(&ts_frame);\n'.format(busnm) + + '\t}\n' + '}\n\n' ) fw('void CANlib_update_can() {\n') for busnm in computer.participation['name']['can'].subscribe.keys(): - fw('\tCANlib_update_can_{}();\n'.format(busnm)) + fw('\tCANlib_Update_can_{}();\n'.format(busnm)) fw('}\n\n') - fw('void CANlib_HandleFrame(CAN_Raw_Bus_T raw_bus, Frame* frame) {\n') - fw('\tswitch(raw_bus) {\n') - for bus in computer.participation['name']['can'].subscribe.keys(): - fw( - '\t\tcase {}:\n'.format(computer.participation['name']['can'].mapping[bus]) + - '\t\t\tCANlib_HandleFrame_{}(frame);\n'.format(bus) + - '\t\t\tbreak;\n' - ) - fw('\t\tdefault:\n\t\t\tUNUSED(frame);\n\t\tbreak;\n') - fw('\t}\n}\n') + fw('void CANlib_HandleFrame(TimestampedFrame *ts_frame, time_t stamp, CAN_TypeDef* instance) {\n') + if len(computer.participation['name']['can'].subscribe.keys()) > 0: # check if computer receives messages + fw('\tts_frame->stamp = stamp;\n') + fw('\tswitch ((intptr_t)instance) {\n') + for bus in computer.participation['name']['can'].subscribe.keys(): + fw( + '\t\tcase (intptr_t){}:\n'.format(raw_bus_to_instance[computer.participation['name']['can'].mapping[ + bus]]) + + '\t\t\tCANlib_HandleFrame_{}(ts_frame);\n'.format(bus) + + '\t\t\tbreak;\n' + ) + fw('\t\tdefault:\n') + fw('\t\t\tbreak;\n') + fw('\t}\n') + else: # prevent unused warning + fw('\tUNUSED(ts_frame);\n') + fw('\tUNUSED(stamp);\n') + fw('\tUNUSED(instance);\n') + fw('}\n') diff --git a/generator/computers_h.py b/generator/computers_h.py index fa02fe7..188ce03 100644 --- a/generator/computers_h.py +++ b/generator/computers_h.py @@ -13,8 +13,8 @@ def declare_pub_frame(frame, name_prepends, fw): def declare_sub_frame(frame, name_prepends, fw): tot_name = coord(name_prepends, frame.name, prefix=False) fw( - 'extern CANlib_{}_T CANlib_{}_Input;\n'.format(tot_name, tot_name) + - 'void CANlib_Handle_{}(Frame *frame);\n'.format(tot_name, tot_name) + 'extern CANlib_{}_Timestamped_T CANlib_{}_Input;\n'.format(tot_name, tot_name) + + 'void CANlib_Handle_{}(TimestampedFrame *frame);\n'.format(tot_name, tot_name) ) @@ -26,7 +26,7 @@ def write(can, computers, output_path=computer_h_dir_path): f_path = os.path.join(output_path, 'canlib_{}.h'.format(computer.name)) if not ('can' in computer.participation['name'].keys()): - # This computer neither sends nor recieves can messagess + # This computer neither sends nor receives can messages continue with open(f_path, 'w') as f: @@ -54,7 +54,7 @@ def write(can, computers, output_path=computer_h_dir_path): for frame in bus: frame_handler(frame, bus_name, declare_pub_frame, fw) except KeyError: - pass # No CAN messages sent by this board + pass # No CAN messages sent by this board fw('\n') @@ -64,12 +64,13 @@ def write(can, computers, output_path=computer_h_dir_path): for frame in bus: frame_handler(frame, bus_name, declare_sub_frame, fw) fw('\n') - fw('void CANlib_update_can(void);\n') - fw('void CANlib_HandleFrame(CAN_Raw_Bus_T raw_bus, Frame* frame);\n') + fw('void CANlib_update_can(void); // for those who still lack CAN interrupts\n') + fw('void CANlib_HandleFrame(TimestampedFrame *ts_frame, time_t stamp, CAN_TypeDef* instance);\n') + fw('bool HAL_CANlib_ReadFrame(CAN_HandleTypeDef *hcan, Frame* out);\n') + fw('bool HAL_CANlib_ReadFrameFromFIFO(CAN_HandleTypeDef *hcan, uint32_t RxFifo, Frame* out);\n') except KeyError: - pass # No CAN messages received by this board + pass # No CAN messages received by this board fw('\n#ifdef __cplusplus\n} // extern "C"\n#endif // __cplusplus\n\n') fw(endif(header_name)) - diff --git a/generator/send_receive.py b/generator/send_receive.py index 85e6921..1830562 100644 --- a/generator/send_receive.py +++ b/generator/send_receive.py @@ -25,13 +25,15 @@ def define_pub_frame(frame, name_prepends, busnm, fw): def define_sub_frame(frame, name_prepends, fw): tot_name = coord(name_prepends, frame.name, prefix=False) - fw('void CANlib_Handle_{}(Frame *frame)'.format( - tot_name, tot_name) + ' {\n' + '\tCANlib_Unpack_{}(frame, &CANlib_{}_Input);\n'.format(tot_name, tot_name) + '}\n\n') + fw('void CANlib_Handle_{}(TimestampedFrame *ts_frame) {{\n'.format(tot_name, tot_name)) + fw('\tCANlib_{}_Input.stamp = ts_frame->stamp;\n'.format(tot_name)) + fw('\tCANlib_Unpack_{}(&(ts_frame->frame), &(CANlib_{}_Input.msg));\n'.format(tot_name,tot_name)) + fw('}\n\n') def define_struct(frame, name_prepends, fw): tot_name = coord(name_prepends, frame.name) - fw('{}_T {}_Input;\n'.format( + fw('{}_Timestamped_T {}_Input;\n'.format( tot_name, tot_name)) diff --git a/generator/structs.py b/generator/structs.py index 50d7be7..f1fe270 100644 --- a/generator/structs.py +++ b/generator/structs.py @@ -17,6 +17,13 @@ def msg_handler(frame, name_prepends, fw): fw('} ' + '{}_T;\n\n'.format(coord(name_prepends, frame.name))) +def timestamped_msg_handler(frame, name_prepends, fw): + fw('typedef struct {\n') + fw('\ttime_t stamp;\n') + fw('\t{}_T msg;\n'.format(coord(name_prepends, frame.name))) + fw('} ' + '{}_Timestamped_T;\n\n'.format(coord(name_prepends, frame.name))) + + def write(can, output_path=structs_path): header_name = '_CAN_LIBRARY_STRUCTS' @@ -25,10 +32,12 @@ def write(can, output_path=structs_path): fw(ifndef(header_name)) fw('#include \n') - fw('#include \n\n') + fw('#include \n') + fw('#include \n') fw('#include "enum_atom.h"\n\n') for bus in can.bus: for msg in bus.frame: frame_handler(msg, bus.name, msg_handler, fw) + frame_handler(msg, bus.name, timestamped_msg_handler, fw) fw(endif(header_name)) diff --git a/src/driver.h b/src/driver.h index 1546ebe..bb0cecd 100644 --- a/src/driver.h +++ b/src/driver.h @@ -3,9 +3,19 @@ #include "drivers/inc/stm32f4xx.h" #include "bus.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus CANlib_Transmit_Error_T CANlib_TransmitFrame(Frame *frame, CANlib_Bus_T bus); -void CANlib_ReadFrame(Frame *frame, CANlib_Bus_T bus); +bool HAL_CANlib_ReadFrame(CAN_HandleTypeDef *hcan, Frame* out); +bool HAL_CANlib_ReadFrameFromFIFO(CAN_HandleTypeDef *hcan, uint32_t RxFifo, Frame* out); CAN_Raw_Bus_T CANlib_GetRawBus(CANlib_Bus_T bus); +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + #endif // __DRIVER_H diff --git a/src/drivers/inc/stm32f4xx.h b/src/drivers/inc/stm32f4xx.h index e77a7c2..710d0f0 100644 --- a/src/drivers/inc/stm32f4xx.h +++ b/src/drivers/inc/stm32f4xx.h @@ -6,12 +6,22 @@ #include "bus.h" #include +#include typedef uint32_t Time_T; // in ms typedef HAL_StatusTypeDef CANlib_Transmit_Error_T; typedef HAL_StatusTypeDef CANlib_Init_Error_T; +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + CANlib_Transmit_Error_T CANlib_TransmitFrame(Frame *frame, CANlib_Bus_T bus); -void CANlib_ReadFrame(Frame *frame, CANlib_Bus_T bus); +bool HAL_CANlib_ReadFrame(CAN_HandleTypeDef *hcan, Frame* out); +bool HAL_CANlib_ReadFrameFromFIFO(CAN_HandleTypeDef *hcan, uint32_t RxFifo, Frame* out); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus #endif // __STM32F4XX_CAN_H diff --git a/src/drivers/src/stm32f4xx.c b/src/drivers/src/stm32f4xx.c index 0802c64..f71bb40 100644 --- a/src/drivers/src/stm32f4xx.c +++ b/src/drivers/src/stm32f4xx.c @@ -5,6 +5,7 @@ #include "driver.h" #include #include +#include extern CAN_HandleTypeDef hcan1; extern CAN_HandleTypeDef hcan2; @@ -47,36 +48,30 @@ HAL_StatusTypeDef CANlib_TransmitFrame(Frame *frame, CANlib_Bus_T bus) { return HAL_CAN_AddTxMessage(hcan, &pHeader, frame->data, &pTxMailbox); } -void CANlib_ReadFrame(Frame *frame, CANlib_Bus_T bus) { - CAN_Raw_Bus_T raw_bus = CANlib_GetRawBus(bus); - CAN_HandleTypeDef *hcan; - switch(raw_bus) { - case CAN_1: - hcan = &hcan1; - break; - case CAN_2: - hcan = &hcan2; - break; - case CAN_3: - hcan = &hcan3; - break; - default: - return; - } +static void HAL_CANlib_ConvertFrame(CAN_RxHeaderTypeDef* pHeader, uint8_t data[8], Frame *out) { + out->id = pHeader->IDE == CAN_ID_STD ? pHeader->StdId : pHeader->ExtId; + out->dlc = pHeader->DLC; + memcpy(out->data, data, 8); + out->extended = pHeader->IDE == CAN_ID_EXT; +} +bool HAL_CANlib_ReadFrameFromFIFO(CAN_HandleTypeDef *hcan, uint32_t RxFifo, Frame* out) { uint8_t data[8] = {}; CAN_RxHeaderTypeDef pHeader; - for (int fifo = 0; fifo < 2; fifo++) { // There are 2 receive FIFOs - if (HAL_CAN_GetRxFifoFillLevel(hcan, fifo) > 0) { - HAL_CAN_GetRxMessage(hcan, fifo, &pHeader, data); - frame->id = pHeader.IDE == CAN_ID_STD ? pHeader.StdId : pHeader.ExtId; - frame->dlc = pHeader.DLC; - - memcpy(frame->data, data, sizeof(data)); - frame->extended = pHeader.IDE == CAN_ID_EXT; - return; - } + if (HAL_CAN_GetRxFifoFillLevel(hcan, RxFifo) > 0) { + if (HAL_CAN_GetRxMessage(hcan, RxFifo, &pHeader, data) == HAL_OK) { + HAL_CANlib_ConvertFrame(&pHeader, data, out); + return true; + } } + return false; } - +bool HAL_CANlib_ReadFrame(CAN_HandleTypeDef *hcan, Frame* out) { + for (uint8_t fifo = 0; fifo < 2; fifo++) { + if (HAL_CANlib_ReadFrameFromFIFO(hcan, fifo, out)) { + return true; + } + } + return false; +} diff --git a/src/static.h b/src/static.h index a79591e..30a8308 100644 --- a/src/static.h +++ b/src/static.h @@ -3,6 +3,7 @@ #include #include +#include typedef struct { uint32_t id; @@ -11,6 +12,11 @@ typedef struct { bool extended; } Frame; +typedef struct { + time_t stamp; + Frame frame; +} TimestampedFrame; + #define LIMIT(name) \ static Time_T last_sent = 0; \ if (HAL_GetTick() - last_sent < name ## _period) return; \