diff --git a/.vscode/launch.json b/.vscode/launch.json index 3681231..672a8ec 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,7 +34,10 @@ "svdFile": "STM32H723.svd", //Path to SVD file to see registers "v1": false, "showDevDebugOutput": "both", - + "liveWatch": { + "enabled": true, + "samplesPerSecond": 4 + } /* Will get automatically detected if STM32CubeIDE is installed to default directory or it can be manually provided if necessary.. */ //"serverpath": "c:\\ST\\STM32CubeIDE_1.7.0\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.0.100.202109301221\\tools\\bin\\ST-LINK_gdbserver.exe", diff --git a/Application/CLS b/Application/CLS index 22e79f7..6ad5136 160000 --- a/Application/CLS +++ b/Application/CLS @@ -1 +1 @@ -Subproject commit 22e79f75e9a84501493a0112f6a7e1172276f498 +Subproject commit 6ad513673d20c89f330f964f763fa042c6ad8013 diff --git a/Application/Tasks/CanDataTask.c b/Application/Tasks/CanDataTask.c index 5018115..9cdf5c8 100644 --- a/Application/Tasks/CanDataTask.c +++ b/Application/Tasks/CanDataTask.c @@ -3,7 +3,8 @@ #include "fdcan.h" #include "CanDataHandler.h" #include "FreeRTOS.h" - +#include "CLSAddress.h" +#include "firmware.pb.h" // Define thread flags #define FLAG_FDCAN_RX_FIFO0 (1<<0) @@ -58,15 +59,6 @@ void CanDataTask_start() { static FDCAN_RxHeaderTypeDef RxHeader; static uint8_t RxData[8]; -void CanDataTask_HandleFifo(uint32_t fifo) { - while (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) > 0 ) { - if (HAL_FDCAN_GetRxMessage(&hfdcan1, fifo, &RxHeader, RxData) != HAL_OK) { - Error_Handler(); - } else { - CanData_canFifo0RxCallback(RxHeader.Identifier,RxData, dlcDecode(RxHeader.DataLength)); - } - } -} // Function for the task void CanDataTask_func(void *argument) { @@ -82,13 +74,37 @@ void CanDataTask_func(void *argument) { Error_Handler(); } + if(HAL_FDCAN_ActivateNotification(&hfdcan1,FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0) != HAL_OK) { + Error_Handler(); + } + + + // setup listening for heartbeats + for (size_t i = 0; i < 16; i++) + { + CanData_regDataMsg(GENERATE_CLS_ADDRESS(CLS_CODE_STATUS, i, CLS_CH_STA_HEATBEAT)); + } + + for(;;) { // wait for interrupt event on any fifo osThreadFlagsWait(FLAG_FDCAN_RX_FIFO0 | FLAG_FDCAN_RX_FIFO1, osFlagsWaitAny, osWaitForever); // check the fifos for data and handle it if nessessay - CanDataTask_HandleFifo(FDCAN_RX_FIFO0); - CanDataTask_HandleFifo(FDCAN_RX_FIFO1); + while (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) > 0 ) { + if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) { + Error_Handler(); + } else { + CanData_canFifo0RxCallback(RxHeader.Identifier,RxData, dlcDecode(RxHeader.DataLength)); + } + } + while (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO1) > 0 ) { + if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO1, &RxHeader, RxData) != HAL_OK) { + Error_Handler(); + } else { + CanData_canFifo1RxCallback(RxHeader.Identifier,RxData, dlcDecode(RxHeader.DataLength)); + } + } } } @@ -101,4 +117,41 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs) { // Notify the thread osThreadFlagsSet(CanDataTask_id, FLAG_FDCAN_RX_FIFO1); +} + + +void DataClbk_ResponseDeviceList(void* msg, uint32_t length) { + // igored +} + + +#include "UsbDataHandler.h" +ResponseDeviceList list; +extern uint8_t gCLS_DEVICE_ADDRESS; +void DataClbk_RequestDeviceList(void* msg, uint32_t length) { + + // add yourself + list.devices[list.devices_count].available = true; + list.devices[list.devices_count].canid = GENERATE_CLS_ADDRESS(CLS_CODE_STATUS, gCLS_DEVICE_ADDRESS, CLS_CH_STA_HEATBEAT); + list.devices[list.devices_count].device = gCLS_DEVICE_ADDRESS; + list.devices[list.devices_count].counter = (osKernelGetTickCount()/500)%256; + list.devices_count++; + + for (size_t i = 0; i < 16; i++) + { + uint16_t canid = (GENERATE_CLS_ADDRESS(CLS_CODE_STATUS, i, CLS_CH_STA_HEATBEAT)); + const CanDataMessage * msg =CanData_getDataMessage(canid); + if(msg) { + if(msg->data_length > 0) { + list.devices[list.devices_count].available = true; + list.devices[list.devices_count].canid = canid; + list.devices[list.devices_count].device = i; + list.devices[list.devices_count].counter = msg->data[0]; + list.devices_count++; + } + } + } + + USBDataResonse(&list, ResponseDeviceList_fields, UsbPackageType_RESPONSE_DEVICE_LIST); + } \ No newline at end of file diff --git a/Application/Tasks/UsbDataHandler.c b/Application/Tasks/UsbDataHandler.c index 4b5a20d..8205951 100644 --- a/Application/Tasks/UsbDataHandler.c +++ b/Application/Tasks/UsbDataHandler.c @@ -49,6 +49,8 @@ union { FirmwarePackage msg_FirmwarePackage; FirmwarePackageAck msg_FirmwarePackageAck; FirmwareDone msg_FirmwareDone; + RequestDeviceList msg_RequestDeviceList; + ResponseDeviceList msg_ResponseDeviceList; } mem_msg_decode; @@ -98,6 +100,8 @@ message_handler_t message_handlers[] = { MESSAGE_HANDLER(UsbPackageType_FIRMWAREPACKAGE, FirmwarePackage), MESSAGE_HANDLER(UsbPackageType_FIRMWAREDONE, FirmwareDone), MESSAGE_HANDLER(UsbPackageType_FIRMWAREPACKAGEACK, FirmwarePackageAck), + MESSAGE_HANDLER(UsbPackageType_REQUEST_DEVICE_LIST, RequestDeviceList), + MESSAGE_HANDLER(UsbPackageType_RESPONSE_DEVICE_LIST, ResponseDeviceList), }; @@ -189,6 +193,25 @@ bool UsbDataPacket_head_check(const UsbDataPacket *p) { return p->head.check == UsbDataPacket_head_sum(p); } +#include "usbd_cdc_if.h" +#include +static UsbDataPacket packet; +void USBDataResonse(void * msg, const pb_msgdesc_t* fields, UsbPackageType typeid) { + pb_ostream_t ostream = pb_ostream_from_buffer(packet.data,sizeof(packet.data)); + bool status = pb_encode(&ostream, fields ,msg); + packet.head.length = ostream.bytes_written; + packet.head.type = typeid; + packet.head.check = UsbDataPacket_head_sum(&packet); + + if(status) { + while (CDC_Transmit_HS((uint8_t*)&packet, packet.head.length + sizeof(UsbDataPacketHead) ) == USBD_BUSY) + { + osDelay(3); + } + } else { + Error_Handler(); + } +} //__attribute__((weak)) void DataClbk_FirmwareStart(void *msg, uint32_t length) {} //__attribute__((weak)) void DataClbk_FirmwarePackage(void *msg, uint32_t length) {} diff --git a/Application/Tasks/UsbDataHandler.h b/Application/Tasks/UsbDataHandler.h index bff3239..e58e5e4 100644 --- a/Application/Tasks/UsbDataHandler.h +++ b/Application/Tasks/UsbDataHandler.h @@ -93,53 +93,17 @@ void UsbDataHandler_Runner(); */ int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len); -/** - * @brief Callback function that is invoked when firmware update message is received. - * - * Other parts of the software can implement this function to handle the start of a firmware update. - * - * @param msg A pointer to the message related to the firmware start. - * @param length The length of the message, in bytes. - * - * @return void - */ - void DataClbk_FirmwareStart(void* msg, uint32_t length); -/** - * @brief Callback function that is invoked when a firmware package message is received. - * - * Other parts of the software can implement this function to handle each received firmware package. - * - * @param msg A pointer to the message related to the received firmware package. - * @param length The length of the message, in bytes. - * - * @return void - */ - void DataClbk_FirmwarePackage(void* msg, uint32_t length); - -/** - * @brief Callback function that is invoked when a firmware package acknowledgment message is received. - * - * Other parts of the software can implement this function to handle the acknowledgment of a received firmware package. - * - * @param msg A pointer to the message related to the firmware package acknowledgment. - * @param length The length of the message, in bytes. - * - * @return void - */ +void DataClbk_FirmwareStart(void* msg, uint32_t length); +void DataClbk_FirmwarePackage(void* msg, uint32_t length); void DataClbk_FirmwarePackageAck(void* msg, uint32_t length); - -/** - * @brief Callback function that is invoked when firmware update done message. - * - * Other parts of the software can implement this function to handle the completion of a firmware update. - * - * @param msg A pointer to the message related to the completion of the firmware update. - * @param length The length of the message, in bytes. - * - * @return void - */ void DataClbk_FirmwareDone(void* msg, uint32_t length); +void DataClbk_ResponseDeviceList(void* msg, uint32_t length); +void DataClbk_RequestDeviceList(void* msg, uint32_t length); + + +#include "firmware.pb.h" +void USBDataResonse(void * msg, const pb_msgdesc_t *fields, UsbPackageType typeid); #ifdef __cplusplus } diff --git a/Core/Src/main.c b/Core/Src/main.c index 98eba6a..bd2a605 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -55,7 +55,7 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ - +uint8_t gCLS_DEVICE_ADDRESS = 0b10001; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -125,6 +125,7 @@ int main(void) MX_RNG_Init(); /* USER CODE BEGIN 2 */ HAL_GPIO_WritePin(Periph_Power_GPIO_Port,Periph_Power_Pin,GPIO_PIN_RESET); + gCLS_DEVICE_ADDRESS = 0b10001; /* USER CODE END 2 */ /* Init scheduler */ diff --git a/proto/firmware.proto b/proto/firmware.proto index 381d0e6..2926a96 100644 --- a/proto/firmware.proto +++ b/proto/firmware.proto @@ -8,6 +8,8 @@ enum UsbPackageType { FIRMWAREPACKAGE = 3842; // 0xF02 FIRMWAREDONE = 3843; // 0xF03 FIRMWAREPACKAGEACK = 3844; // 0xF04 + REQUEST_DEVICE_LIST = 1000; + RESPONSE_DEVICE_LIST = 1001; } message FirmwareStart { @@ -38,3 +40,18 @@ message FirmwareDone { required uint32 device_id = 3; } + +message RequestDeviceList { + required uint32 msg =1; +} + +message Device { + required bool available =1; + required uint32 canid = 2; + required uint32 device = 3; + required uint32 counter = 4; +} + +message ResponseDeviceList { + repeated Device devices = 1 [(nanopb).max_count = 18]; +} \ No newline at end of file diff --git a/tools/find_devices.py b/tools/find_devices.py new file mode 100644 index 0000000..9a56212 --- /dev/null +++ b/tools/find_devices.py @@ -0,0 +1,71 @@ +import serial +import struct +from google.protobuf.message import DecodeError +from serial.tools import list_ports + +from firmware_pb2 import RequestDeviceList, Device, ResponseDeviceList, UsbPackageType + +def make_header(typeid: UsbPackageType, length: int) -> bytearray: + struct_format = '> 8) & 0xFF) + (typeidint & 0xFF) + ((typeidint >> 8) & 0xFF) + packed_data = struct.pack(struct_format, length, typeid, check) + return packed_data + +def send_package(typeid : UsbPackageType, data: bytearray, serial: serial.Serial): + head = make_header(typeid, len(data)) + package = head + data + serial.write(package) + +if __name__ == "__main__": + stm_port = None + for port in list_ports.comports(): + print(port) + if "STM32 Virtual ComPort" in port.description: + stm_port = port.device + break + + if stm_port is None: + print("STM32 Virtual ComPort not found") + exit(-1) + else: + # Open the serial port + ser = serial.Serial(stm_port,baudrate=5000000) + + + # Create a RequestDeviceList message + request = RequestDeviceList() + request.msg = 1 # or whatever value you want to set + + # Serialize the request to a bytearray + request_data = request.SerializeToString() + + # Send the request + send_package(UsbPackageType.REQUEST_DEVICE_LIST, request_data, ser) + + # Now wait for the response + while True: + # Read the header from the serial port + response_header = ser.read(5) # assuming the header is 5 bytes long + + # Unpack the header to get the length and type + length, typeid, check = struct.unpack('