Compare commits
20 Commits
feature/Li
...
refactor/V
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d02489b16 | |||
| 452246951b | |||
| eb5733da97 | |||
| 766d5e9ca8 | |||
| 9c489c1a25 | |||
| d0544576a3 | |||
| 66e04c6e06 | |||
| 9b49028c20 | |||
| 13c6a71af6 | |||
| c7d6ba78d5 | |||
| 804c4c8c69 | |||
| a91fdc9311 | |||
| fd3757b6a1 | |||
| 2b12ea9602 | |||
| e892a21f97 | |||
| 1a1e4bbee4 | |||
| c3322ed571 | |||
| bd8779b5aa | |||
| 04c5eb047e | |||
| 1d7ad7dc31 |
@@ -8,7 +8,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: apt-get update && apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi ninja-build cmake protobuf-compiler python3 python3-grpcio python3-protobuf python3-pkg-resources
|
run: apt-get update && apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi ninja-build cmake protobuf-compiler python3 python3-grpcio python3-protobuf python3-pkg-resources python3-requests
|
||||||
# run: pip install setuptools
|
# run: pip install setuptools
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -32,3 +32,8 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
build/*.hex
|
build/*.hex
|
||||||
build/*.bin
|
build/*.bin
|
||||||
|
|
||||||
|
- name: Upload Firmware
|
||||||
|
env:
|
||||||
|
SERVER_KEY: ${{ secrets.SERVER_KEY }}
|
||||||
|
run: python3 tools/upload_firmware.py $SERVER_KEY
|
||||||
27
.vscode/launch.json
vendored
27
.vscode/launch.json
vendored
@@ -44,6 +44,33 @@
|
|||||||
//"armToolchainPath": "c:\\ST\\STM32CubeIDE_1.7.0\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\\tools\\bin",
|
//"armToolchainPath": "c:\\ST\\STM32CubeIDE_1.7.0\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\\tools\\bin",
|
||||||
//"stm32cubeprogrammer": "c:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin",
|
//"stm32cubeprogrammer": "c:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin",
|
||||||
|
|
||||||
|
/* If you use external loader, add additional arguments */
|
||||||
|
//"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Attach Microcontroller - ST-Link",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"type": "cortex-debug",
|
||||||
|
"executable": "${command:cmake.launchTargetPath}", //or fixed file path: build/stm32h735g-dk-led.elf
|
||||||
|
"request": "attach", //Use "attach" to connect to target w/o elf download
|
||||||
|
"servertype": "stlink",
|
||||||
|
"device": "STM32H723VGT", //MCU used, ex. "STM32H735IG"
|
||||||
|
"interface": "swd",
|
||||||
|
"serialNumber": "002800223232511939353236", //Set ST-Link ID if you use multiple at the same time
|
||||||
|
"runToEntryPoint": "main",
|
||||||
|
"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",
|
||||||
|
//"armToolchainPath": "c:\\ST\\STM32CubeIDE_1.7.0\\STM32CubeIDE\\plugins\\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\\tools\\bin",
|
||||||
|
//"stm32cubeprogrammer": "c:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin",
|
||||||
|
|
||||||
/* If you use external loader, add additional arguments */
|
/* If you use external loader, add additional arguments */
|
||||||
//"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
|
//"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void BSP_ADC_Start()
|
|||||||
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
|
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
|
||||||
{
|
{
|
||||||
/* Invalidate Data Cache to get the updated content of the SRAM on the first half of the ADC converted data buffer: 32 bytes */
|
/* Invalidate Data Cache to get the updated content of the SRAM on the first half of the ADC converted data buffer: 32 bytes */
|
||||||
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[0], ADC_CONVERTED_DATA_BUFFER_SIZE);
|
//SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[0], ADC_CONVERTED_DATA_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +58,7 @@ void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
|
|||||||
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
|
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
|
||||||
{
|
{
|
||||||
/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
|
/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
|
||||||
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE/2], ADC_CONVERTED_DATA_BUFFER_SIZE);
|
//SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE/2], ADC_CONVERTED_DATA_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,14 @@
|
|||||||
#include "cmsis_os2.h"
|
#include "cmsis_os2.h"
|
||||||
#include "BSP_GPIO.h"
|
#include "BSP_GPIO.h"
|
||||||
#include "BSP_ADC.h"
|
#include "BSP_ADC.h"
|
||||||
|
#include "BSP_SDLogger.h"
|
||||||
#define LPTIM_CLK 500 // Hz
|
#define LPTIM_CLK 500 // Hz
|
||||||
#define SLEEP_TICK_TIME 1 // seconds to wait
|
#define SLEEP_TICK_TIME 1 // seconds to wait
|
||||||
#define STAY_AWAKE_TIME 60 // seconds to stay awake without K15
|
#define STAY_AWAKE_TIME 60 // seconds to stay awake without K15
|
||||||
|
|
||||||
|
|
||||||
|
bool CanDataTask_CarCanActive();
|
||||||
|
|
||||||
|
|
||||||
// Start the sleep counter check
|
// Start the sleep counter check
|
||||||
void BSP_POWER_Init() {
|
void BSP_POWER_Init() {
|
||||||
@@ -52,6 +54,15 @@ void BSP_POWER_WakeUp() {
|
|||||||
*/
|
*/
|
||||||
void BSP_POWER_EnterStandby() {
|
void BSP_POWER_EnterStandby() {
|
||||||
|
|
||||||
|
// if there is still communication on the CAN bus, we should not go to standby
|
||||||
|
// intstead we should reset the system, because the CAN bus would wake us up again
|
||||||
|
if (CanDataTask_CarCanActive()) {
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the sytem interrupts
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
// We need to disable all Periperals to minimize parasitic currents
|
// We need to disable all Periperals to minimize parasitic currents
|
||||||
HAL_I2C_DeInit(&hi2c1);
|
HAL_I2C_DeInit(&hi2c1);
|
||||||
HAL_I2C_MspDeInit(&hi2c1);
|
HAL_I2C_MspDeInit(&hi2c1);
|
||||||
@@ -108,6 +119,13 @@ void BSP_POWER_EnterStandby() {
|
|||||||
/* Enter the Standby mode */
|
/* Enter the Standby mode */
|
||||||
HAL_PWR_EnterSTANDBYMode();
|
HAL_PWR_EnterSTANDBYMode();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// if we are here, something went wrong
|
||||||
|
NVIC_SystemReset();
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sec_without_k15 = 0;
|
uint32_t sec_without_k15 = 0;
|
||||||
|
|||||||
110
Application/BSP/BSP_SDLogger.c
Normal file
110
Application/BSP/BSP_SDLogger.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include "BSP_SDLogger.h"
|
||||||
|
#include "fatfs.h"
|
||||||
|
#include "ulog.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
uint8_t block_buffer[512] = {0};
|
||||||
|
size_t block_buffer_index = 0;
|
||||||
|
char file_name[20];
|
||||||
|
|
||||||
|
char ulog_buffer[ULOG_MAX_MESSAGE_LENGTH] = {0};
|
||||||
|
|
||||||
|
void BSP_SDLogger_ULOG(ulog_level_t level, char *msg) {
|
||||||
|
uint32_t send_length = snprintf(ulog_buffer, ULOG_MAX_MESSAGE_LENGTH, "[%s] %s\n", ulog_level_name(level), msg);
|
||||||
|
BSP_SDLogger_Write(ulog_buffer, send_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
// Define the mutex
|
||||||
|
osMutexId_t logger_mutex;
|
||||||
|
|
||||||
|
// init the logger buffer and the file
|
||||||
|
// filename is generated based on the log number
|
||||||
|
void BSP_SDLogger_Init(int log_number) {
|
||||||
|
|
||||||
|
// create the file name
|
||||||
|
sprintf(file_name, "log_%d.txt", log_number);
|
||||||
|
|
||||||
|
// open the file
|
||||||
|
FIL file;
|
||||||
|
FRESULT res = f_open(&file, file_name, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
ULOG_ERROR("Failed to open file %s", file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ULOG_SUBSCRIBE(BSP_SDLogger_ULOG, ULOG_DEBUG_LEVEL);
|
||||||
|
|
||||||
|
// close the file
|
||||||
|
f_close(&file);
|
||||||
|
|
||||||
|
// Create the mutex
|
||||||
|
logger_mutex = osMutexNew(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this fuctions assumes you have the mutex
|
||||||
|
void BSP_SDLogger_Flush_private() {
|
||||||
|
// open the file
|
||||||
|
FIL file;
|
||||||
|
FRESULT res = f_open(&file, file_name, FA_OPEN_APPEND | FA_WRITE );
|
||||||
|
if (res != FR_OK) {
|
||||||
|
ULOG_ERROR("Failed to open file %s", file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the buffer to the file
|
||||||
|
UINT bytes_written;
|
||||||
|
res = f_write(&file, block_buffer, block_buffer_index, &bytes_written);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
ULOG_ERROR("Failed to write to file %s", file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the file
|
||||||
|
f_close(&file);
|
||||||
|
|
||||||
|
// reset the buffer index
|
||||||
|
block_buffer_index = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BSP_SDLogger_Flush() {
|
||||||
|
// Acquire the mutex
|
||||||
|
osMutexAcquire(logger_mutex, osWaitForever);
|
||||||
|
|
||||||
|
// flush the buffer
|
||||||
|
BSP_SDLogger_Flush_private();
|
||||||
|
|
||||||
|
// Release the mutex
|
||||||
|
osMutexRelease(logger_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write data to the logger
|
||||||
|
// data is only written to the buffer!
|
||||||
|
// once the buffer is full, the data is written to the file
|
||||||
|
void BSP_SDLogger_Write(char *data, size_t length) {
|
||||||
|
// Acquire the mutex
|
||||||
|
osMutexAcquire(logger_mutex, osWaitForever);
|
||||||
|
|
||||||
|
size_t buffer_size = sizeof(block_buffer);
|
||||||
|
size_t remaining_size = buffer_size - block_buffer_index;
|
||||||
|
|
||||||
|
// if the data is larger than the remaining space in the buffer
|
||||||
|
if (length > remaining_size) {
|
||||||
|
// write the remaining space to the buffer
|
||||||
|
memcpy(&block_buffer[block_buffer_index], data, remaining_size);
|
||||||
|
block_buffer_index += remaining_size;
|
||||||
|
// write the buffer to the file
|
||||||
|
BSP_SDLogger_Flush_private();
|
||||||
|
// write the remaining data to the buffer
|
||||||
|
memcpy(&block_buffer[block_buffer_index], &data[remaining_size], length - remaining_size);
|
||||||
|
block_buffer_index = length - remaining_size;
|
||||||
|
} else {
|
||||||
|
// write the data to the buffer
|
||||||
|
memcpy(&block_buffer[block_buffer_index], data, length);
|
||||||
|
block_buffer_index += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the mutex
|
||||||
|
osMutexRelease(logger_mutex);
|
||||||
|
}
|
||||||
@@ -2,3 +2,13 @@
|
|||||||
// buffernd logger collect logs until some amount of data is collected.
|
// buffernd logger collect logs until some amount of data is collected.
|
||||||
// needs to be flushed before shutdown
|
// needs to be flushed before shutdown
|
||||||
// used with ULOG
|
// used with ULOG
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void BSP_SDLogger_Init(int log_number);
|
||||||
|
|
||||||
|
|
||||||
|
void BSP_SDLogger_Write(char *data, size_t length);
|
||||||
|
|
||||||
|
void BSP_SDLogger_Flush();
|
||||||
@@ -5,6 +5,7 @@ BSP_INA.c
|
|||||||
BSP_POWER.c
|
BSP_POWER.c
|
||||||
BSP_GPIO.c
|
BSP_GPIO.c
|
||||||
BSP_ADC.c
|
BSP_ADC.c
|
||||||
|
BSP_SDLogger.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(BSP PUBLIC ./)
|
target_include_directories(BSP PUBLIC ./)
|
||||||
|
|||||||
Submodule Application/CLS updated: 2934954396...4744762b4c
@@ -1,4 +1,5 @@
|
|||||||
#include "CLS_BSP.h"
|
#include "CLS_BSP.h"
|
||||||
|
#include "CLSAddress.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef CLS_BSP_FDCAN
|
#ifdef CLS_BSP_FDCAN
|
||||||
@@ -25,6 +26,31 @@ HAL_StatusTypeDef CLS_BSP_CAN_SetUniversalFilter(const CLS_BSP_CAN_UniversalFilt
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t CLS_BSP_DLC_ToBytes(uint32_t dlc) {
|
||||||
|
|
||||||
|
switch (dlc) {
|
||||||
|
case CLS_BSP_DLC_BYTES_1:
|
||||||
|
return 1;
|
||||||
|
case CLS_BSP_DLC_BYTES_2:
|
||||||
|
return 2;
|
||||||
|
case CLS_BSP_DLC_BYTES_3:
|
||||||
|
return 3;
|
||||||
|
case CLS_BSP_DLC_BYTES_4:
|
||||||
|
return 4;
|
||||||
|
case CLS_BSP_DLC_BYTES_5:
|
||||||
|
return 5;
|
||||||
|
case CLS_BSP_DLC_BYTES_6:
|
||||||
|
return 6;
|
||||||
|
case CLS_BSP_DLC_BYTES_7:
|
||||||
|
return 7;
|
||||||
|
case CLS_BSP_DLC_BYTES_8:
|
||||||
|
return 8;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CLS_Type_t CLS_BSP_GetDeviceType(void) {
|
CLS_Type_t CLS_BSP_GetDeviceType(void) {
|
||||||
return cls_device_Type_MASTER;
|
return cls_device_Type_MASTER;
|
||||||
@@ -43,3 +69,8 @@ CLS_Position_t CLS_BSP_GetPosition(void) {
|
|||||||
|
|
||||||
void CLS_BSP_SetPosition(CLS_Position_t position) {
|
void CLS_BSP_SetPosition(CLS_Position_t position) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "BSP_GPIO.h"
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ typedef FDCAN_TxHeaderTypeDef CLS_BSP_TxHeaderType;
|
|||||||
#define CLS_BSP_DLC_BYTES_7 FDCAN_DLC_BYTES_7
|
#define CLS_BSP_DLC_BYTES_7 FDCAN_DLC_BYTES_7
|
||||||
#define CLS_BSP_DLC_BYTES_8 FDCAN_DLC_BYTES_8
|
#define CLS_BSP_DLC_BYTES_8 FDCAN_DLC_BYTES_8
|
||||||
|
|
||||||
|
// function to convert DLC to bytes
|
||||||
|
uint8_t CLS_BSP_DLC_ToBytes(uint32_t dlc);
|
||||||
|
|
||||||
#define CLS_CAN_FILTER_DISABLE FDCAN_FILTER_DISABLE
|
#define CLS_CAN_FILTER_DISABLE FDCAN_FILTER_DISABLE
|
||||||
#define CLS_CAN_FILTER_TO_RXFIFO0 FDCAN_FILTER_TO_RXFIFO0
|
#define CLS_CAN_FILTER_TO_RXFIFO0 FDCAN_FILTER_TO_RXFIFO0
|
||||||
#define CLS_CAN_FILTER_TO_RXFIFO1 FDCAN_FILTER_TO_RXFIFO1
|
#define CLS_CAN_FILTER_TO_RXFIFO1 FDCAN_FILTER_TO_RXFIFO1
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ target_sources(${PROJECT_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE CLS)
|
target_link_libraries(${PROJECT_NAME} PRIVATE CLS BSP Vehicle)
|
||||||
@@ -2,3 +2,5 @@ add_subdirectory(Tasks)
|
|||||||
add_subdirectory(CLS)
|
add_subdirectory(CLS)
|
||||||
add_subdirectory(CLS_BSP)
|
add_subdirectory(CLS_BSP)
|
||||||
add_subdirectory(BSP)
|
add_subdirectory(BSP)
|
||||||
|
add_subdirectory(ram_loader)
|
||||||
|
add_subdirectory(Vehicle)
|
||||||
@@ -22,4 +22,4 @@ target_sources(${PROJECT_NAME}
|
|||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC PROTOS CLS)
|
target_link_libraries(${PROJECT_NAME} PUBLIC PROTOS CLS)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE Revision CLS_BSP BSP ulog)
|
target_link_libraries(${PROJECT_NAME} PRIVATE Revision CLS_BSP BSP ulog Vehicle ram_loader)
|
||||||
@@ -9,6 +9,9 @@
|
|||||||
#include "usb.pb.h"
|
#include "usb.pb.h"
|
||||||
#include "version_info.h"
|
#include "version_info.h"
|
||||||
#include "ulog.h"
|
#include "ulog.h"
|
||||||
|
#include "BSP_POWER.h"
|
||||||
|
#include "BSP_GPIO.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
// Define thread flags
|
// Define thread flags
|
||||||
#define FLAG_FDCAN_RX_FIFO0 (1<<0)
|
#define FLAG_FDCAN_RX_FIFO0 (1<<0)
|
||||||
#define FLAG_FDCAN_RX_FIFO1 (1<<1)
|
#define FLAG_FDCAN_RX_FIFO1 (1<<1)
|
||||||
@@ -31,7 +34,7 @@ const osThreadAttr_t CanDataTask_attr = {
|
|||||||
|
|
||||||
// Memory for the task
|
// Memory for the task
|
||||||
StaticTask_t CarCanTask_cb;
|
StaticTask_t CarCanTask_cb;
|
||||||
uint32_t CarCanTask_stk[256];
|
uint32_t CarCanTask_stk[512];
|
||||||
// Attributes for the task
|
// Attributes for the task
|
||||||
osThreadId_t CarCanTask_id;
|
osThreadId_t CarCanTask_id;
|
||||||
const osThreadAttr_t CarCanTask_attr = {
|
const osThreadAttr_t CarCanTask_attr = {
|
||||||
@@ -44,7 +47,7 @@ const osThreadAttr_t CarCanTask_attr = {
|
|||||||
.priority = osPriorityNormal,
|
.priority = osPriorityNormal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint64_t last_car_message_time = 0;
|
||||||
|
|
||||||
uint32_t dlcDecode(uint32_t dlcCode) {
|
uint32_t dlcDecode(uint32_t dlcCode) {
|
||||||
switch(dlcCode) {
|
switch(dlcCode) {
|
||||||
@@ -128,7 +131,6 @@ void CanDataTask_func(void *argument) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t last_car_message_time = UINT64_MAX;
|
|
||||||
|
|
||||||
// convert byte to 2 hex characters
|
// convert byte to 2 hex characters
|
||||||
void byteToHex(uint8_t byte, char * hex) {
|
void byteToHex(uint8_t byte, char * hex) {
|
||||||
@@ -137,13 +139,22 @@ void byteToHex(uint8_t byte, char * hex) {
|
|||||||
hex[1] = hexLookup[byte & 0x0F];
|
hex[1] = hexLookup[byte & 0x0F];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FDCAN_RxHeaderTypeDef RxHeader = {0};
|
||||||
|
static uint8_t RxData[8] = {0};
|
||||||
|
|
||||||
void CarCanTask_func(void *argument) {
|
void CarCanTask_func(void *argument) {
|
||||||
|
|
||||||
// for testing accept all messages from the car can bus
|
// for testing accept all messages from the car can bus
|
||||||
|
// put unkown messages in fifo 0
|
||||||
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) {
|
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) {
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vehicle_Setup_CAN();
|
||||||
|
|
||||||
|
|
||||||
/* Start the FDCAN module */
|
/* Start the FDCAN module */
|
||||||
if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK){
|
if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK){
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
@@ -153,8 +164,7 @@ void CarCanTask_func(void *argument) {
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
FDCAN_RxHeaderTypeDef RxHeader;
|
|
||||||
uint8_t RxData[8];
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// wait for interrupt event on any fifo
|
// wait for interrupt event on any fifo
|
||||||
@@ -166,7 +176,7 @@ void CarCanTask_func(void *argument) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// do something with the can data
|
// do something with the can data
|
||||||
last_car_message_time = osKernelGetTickCount();
|
//last_car_message_time = osKernelGetTickCount();
|
||||||
char msg[17] = {0};
|
char msg[17] = {0};
|
||||||
|
|
||||||
switch (RxHeader.DataLength)
|
switch (RxHeader.DataLength)
|
||||||
@@ -230,7 +240,7 @@ void CarCanTask_func(void *argument) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULOG_DEBUG("Car MSG: %x, %d %s", RxHeader.Identifier, RxHeader.DataLength, msg);
|
//ULOG_DEBUG("Car MSG: %x, %d %s", RxHeader.Identifier,CLS_BSP_DLC_ToBytes(RxHeader.DataLength) , msg);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,9 +249,9 @@ void CarCanTask_func(void *argument) {
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// do something with the can data
|
Vehicle_Receive_CAN(RxHeader, RxData);
|
||||||
last_car_message_time = osKernelGetTickCount();
|
|
||||||
|
|
||||||
|
//ULOG_DEBUG("Used Car MSG: %x, %d %s", RxHeader.Identifier, CLS_BSP_DLC_ToBytes(RxHeader.DataLength), msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,10 +263,18 @@ void CarCanTask_func(void *argument) {
|
|||||||
* @return true if a car can message has been received
|
* @return true if a car can message has been received
|
||||||
* @return false if no car can message has been received
|
* @return false if no car can message has been received
|
||||||
*/
|
*/
|
||||||
bool CanDataTask_gotCarCanMessage() {
|
|
||||||
return last_car_message_time != UINT64_MAX;
|
|
||||||
|
bool CanDataTask_CarCanActive() {
|
||||||
|
if (last_car_message_time == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return osKernelGetTickCount() - last_car_message_time < 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
|
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
|
||||||
// Notify the thread
|
// Notify the thread
|
||||||
if(hfdcan == &hfdcan1) {
|
if(hfdcan == &hfdcan1) {
|
||||||
@@ -264,8 +282,15 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hfdcan == &hfdcan2) {
|
if(hfdcan == &hfdcan2) {
|
||||||
osThreadFlagsSet(CarCanTask_id, FLAG_FDCAN_RX_FIFO0);
|
last_car_message_time = osKernelGetTickCount();
|
||||||
|
|
||||||
|
while (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan2, FDCAN_RX_FIFO0) > 0 ) {
|
||||||
|
FDCAN_RxHeaderTypeDef RxHeader;
|
||||||
|
uint8_t RxData[8];
|
||||||
|
HAL_FDCAN_GetRxMessage(&hfdcan2, FDCAN_RX_FIFO0, &RxHeader, RxData);
|
||||||
|
//ignore the message for now
|
||||||
|
}
|
||||||
|
//osThreadFlagsSet(CarCanTask_id, FLAG_FDCAN_RX_FIFO0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +301,7 @@ void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hfdcan == &hfdcan2) {
|
if(hfdcan == &hfdcan2) {
|
||||||
|
last_car_message_time = osKernelGetTickCount();
|
||||||
osThreadFlagsSet(CarCanTask_id, FLAG_FDCAN_RX_FIFO1);
|
osThreadFlagsSet(CarCanTask_id, FLAG_FDCAN_RX_FIFO1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
void CanDataTask_start();
|
void CanDataTask_start();
|
||||||
|
|
||||||
|
|
||||||
bool CanDataTask_gotCarCanMessage();
|
bool CanDataTask_gotCarCanMessage();
|
||||||
|
|
||||||
|
bool CanDataTask_CarCanActive();
|
||||||
|
|
||||||
|
uint8_t CanDataTask_CarCanBrightness();
|
||||||
|
float CanDataTask_CarCanSpeed();
|
||||||
|
int CanDataTask_CarCanDirectionIsForward();
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "FirmwareUpdate.h"
|
#include "FirmwareUpdate.h"
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
|
#include "CLS.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "ram_loader.h"
|
||||||
|
|
||||||
// static memory only for decoding messages
|
// static memory only for decoding messages
|
||||||
static cls_firmware_Start msg_cls_firmware_Start;
|
static cls_firmware_Start msg_cls_firmware_Start;
|
||||||
@@ -58,19 +61,15 @@ void DataSend_FirmwareFileCheck(uint32_t crc, uint32_t device_id, bool ready_for
|
|||||||
#define CHUNK_SIZE 256 // Change this to the size of chunks you want to read
|
#define CHUNK_SIZE 256 // Change this to the size of chunks you want to read
|
||||||
static uint8_t crc_buffer[CHUNK_SIZE];
|
static uint8_t crc_buffer[CHUNK_SIZE];
|
||||||
|
|
||||||
void DataClbk_cls_firmware_Start(void *msg, uint32_t length) {
|
|
||||||
DATA_CLBK_SETUP(cls_firmware_Start);
|
void fw_Start_Slave( cls_firmware_Start * msg) {
|
||||||
fwStartTime = osKernelGetSysTimerCount();
|
|
||||||
fwPackageCounter = 0;
|
|
||||||
uint32_t crc = 0;
|
uint32_t crc = 0;
|
||||||
UINT totalRead = 0;
|
UINT totalRead = 0;
|
||||||
UINT bytesRead = 0;
|
UINT bytesRead = 0;
|
||||||
|
|
||||||
if(FileOpen) {
|
|
||||||
f_close(&FwFile);
|
|
||||||
}
|
|
||||||
// Check if file already exists
|
// Check if file already exists
|
||||||
if(f_open(&FwFile, msg_cls_firmware_Start.name, FA_READ) == FR_OK) {
|
if(f_open(&FwFile, msg->name, FA_READ) == FR_OK) {
|
||||||
|
|
||||||
__HAL_CRC_DR_RESET(&hcrc);
|
__HAL_CRC_DR_RESET(&hcrc);
|
||||||
do {
|
do {
|
||||||
@@ -80,16 +79,38 @@ void DataClbk_cls_firmware_Start(void *msg, uint32_t length) {
|
|||||||
} while(bytesRead == CHUNK_SIZE);
|
} while(bytesRead == CHUNK_SIZE);
|
||||||
f_close(&FwFile);
|
f_close(&FwFile);
|
||||||
|
|
||||||
if(crc == msg_cls_firmware_Start.crc_fw) {
|
if(crc == msg->crc_fw) {
|
||||||
// CRC matches, no need for transfer
|
// CRC matches, no need for transfer
|
||||||
DataSend_FirmwareFileCheck(crc, msg_cls_firmware_Start.device_id, false, totalRead, msg_cls_firmware_Start.name);
|
DataSend_FirmwareFileCheck(crc, msg->device_id, false, totalRead, msg->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fresult_open = f_open(&FwFile, msg_cls_firmware_Start.name, FA_CREATE_ALWAYS | FA_WRITE);
|
fresult_open = f_open(&FwFile, msg->name, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
FileOpen=true;
|
FileOpen=true;
|
||||||
DataSend_FirmwareFileCheck(crc, msg_cls_firmware_Start.device_id, fresult_open==FR_OK, totalRead, msg_cls_firmware_Start.name);
|
DataSend_FirmwareFileCheck(crc, msg->device_id, fresult_open==FR_OK, totalRead, msg->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fw_Start_Master( cls_firmware_Start * msg) {
|
||||||
|
fresult_open = f_open(&FwFile, "firm.bin", FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
|
FileOpen=true;
|
||||||
|
DataSend_FirmwareFileCheck(0, msg->device_id, fresult_open==FR_OK, 0, msg->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataClbk_cls_firmware_Start(void *msg, uint32_t length) {
|
||||||
|
DATA_CLBK_SETUP(cls_firmware_Start);
|
||||||
|
fwStartTime = osKernelGetSysTimerCount();
|
||||||
|
fwPackageCounter = 0;
|
||||||
|
|
||||||
|
if(FileOpen) {
|
||||||
|
f_close(&FwFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msg_cls_firmware_Start.device_id == gCLS_DEVICE_ADDRESS) {
|
||||||
|
fw_Start_Master(&msg_cls_firmware_Start);
|
||||||
|
} else {
|
||||||
|
fw_Start_Slave(&msg_cls_firmware_Start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,10 +154,14 @@ void DataClbk_cls_firmware_Done(void *msg, uint32_t length) {
|
|||||||
fresult_open = 0xFF;
|
fresult_open = 0xFF;
|
||||||
FileOpen=false;
|
FileOpen=false;
|
||||||
|
|
||||||
|
if(msg_cls_firmware_Done.device_id == gCLS_DEVICE_ADDRESS) {
|
||||||
|
RamLoader_LoadApplication();
|
||||||
|
} else {
|
||||||
|
|
||||||
FirmwareUpdateArgs args;
|
FirmwareUpdateArgs args;
|
||||||
args.device = msg_cls_firmware_Done.device_id;
|
args.device = msg_cls_firmware_Done.device_id;
|
||||||
memcpy(args.name, msg_cls_firmware_Start.name, sizeof(args.name));
|
memcpy(args.name, msg_cls_firmware_Start.name, sizeof(args.name));
|
||||||
|
|
||||||
FirmwareUpdateTask_start(args);
|
FirmwareUpdateTask_start(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,6 @@ void FirmwareUpdateTask_start(FirmwareUpdateArgs args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UsbDataPacket buffer;
|
|
||||||
void CLSFirmwareUpdateTask_func(void *argument) {
|
void CLSFirmwareUpdateTask_func(void *argument) {
|
||||||
FirmwareUpdateArgs args;
|
FirmwareUpdateArgs args;
|
||||||
osStatus_t status;
|
osStatus_t status;
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
#include "BSP_ADC.h"
|
#include "BSP_ADC.h"
|
||||||
#include "LightTask.h"
|
#include "LightTask.h"
|
||||||
#include "ulog.h"
|
#include "ulog.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
// Create the task with a specific priority and stack size
|
// Create the task with a specific priority and stack size
|
||||||
osThreadAttr_t task_attr = {
|
osThreadAttr_t task_attr = {
|
||||||
.name = "LightStateTask",
|
.name = "LightStateTask",
|
||||||
.priority = osPriorityNormal,
|
.priority = osPriorityNormal,
|
||||||
.stack_size = 1024
|
.stack_size = 2048
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function prototype for the task function
|
// Function prototype for the task function
|
||||||
@@ -23,89 +25,15 @@ void LightStateTask_start(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check if K15 is on for switching the light state
|
|
||||||
static bool isK15On()
|
|
||||||
{
|
|
||||||
return BSP_GPIO_K15isSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Define the threshold voltage for engine running
|
|
||||||
#define ENGINE_RUNNING_THRESHOLD 13.3 // 13.5V
|
|
||||||
|
|
||||||
// Define thresholds with hysteresis
|
|
||||||
#define ENGINE_RUNNING_THRESHOLD_HIGH (ENGINE_RUNNING_THRESHOLD + 0.125)
|
|
||||||
#define ENGINE_RUNNING_THRESHOLD_LOW (ENGINE_RUNNING_THRESHOLD - 0.125)
|
|
||||||
|
|
||||||
// Global variable to store the current engine state
|
|
||||||
static bool engineRunning = false;
|
|
||||||
|
|
||||||
// Function to initialize the engine state based on the initial voltage
|
|
||||||
static void initializeEngineState()
|
|
||||||
{
|
|
||||||
float initialVoltage = BSP_ADC_ReadBusValue();
|
|
||||||
if (initialVoltage > ENGINE_RUNNING_THRESHOLD)
|
|
||||||
{
|
|
||||||
engineRunning = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
engineRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the engine state is initialized once
|
|
||||||
static bool isEngineInitialized = false;
|
|
||||||
|
|
||||||
static bool isEngineRunning()
|
|
||||||
{
|
|
||||||
if (!isEngineInitialized)
|
|
||||||
{
|
|
||||||
initializeEngineState();
|
|
||||||
isEngineInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float voltage = BSP_ADC_ReadBusValue();
|
|
||||||
|
|
||||||
if (engineRunning)
|
|
||||||
{
|
|
||||||
// If engine is currently running, use the lower threshold to turn it off
|
|
||||||
if (voltage < ENGINE_RUNNING_THRESHOLD_LOW)
|
|
||||||
{
|
|
||||||
engineRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If engine is currently off, use the higher threshold to turn it on
|
|
||||||
if (voltage > ENGINE_RUNNING_THRESHOLD_HIGH)
|
|
||||||
{
|
|
||||||
engineRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return engineRunning;
|
|
||||||
}
|
|
||||||
// check if the headlight is on and the engine is running to switch the light state
|
|
||||||
// we can check the headlight using the GPIO functions
|
|
||||||
static bool isHeadlightOn()
|
|
||||||
{
|
|
||||||
return BSP_GPIO_HeadLightIsSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function to determine the next state of the light
|
// Function to determine the next state of the light
|
||||||
// return 1 as default state
|
// return 1 as default state
|
||||||
// return 2 if the engine is running
|
// return 2 if the engine is running
|
||||||
// return 3 if the headlight and engine is running
|
// return 3 if the headlight and engine is running
|
||||||
static int determineNextState()
|
static int determineNextState()
|
||||||
{
|
{
|
||||||
if (isHeadlightOn() && isEngineRunning()) {
|
if (Vehicle_isHeadlightOn() && Vehicle_isEngineRunning()) {
|
||||||
return 2;
|
return 2;
|
||||||
} else if (isEngineRunning()) {
|
} else if (Vehicle_isEngineRunning()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "BSP_EE24.h"
|
#include "BSP_EE24.h"
|
||||||
#include "LightTask.h"
|
#include "LightTask.h"
|
||||||
#include "CanDataHandler.h"
|
#include "CanDataHandler.h"
|
||||||
|
#include "BSP_GPIO.h"
|
||||||
|
|
||||||
|
#include "CanDataTask.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
#include "BSP_ADC.h"
|
#include "BSP_ADC.h"
|
||||||
#define DIMM_DEADZONE_VOLTAGE 0.7
|
#define DIMM_DEADZONE_VOLTAGE 0.7
|
||||||
|
|
||||||
@@ -76,22 +80,35 @@ void LightTask_func(void *argument) {
|
|||||||
// calculate the brightness to send
|
// calculate the brightness to send
|
||||||
uint8_t brightness = lightSettings.brightness;
|
uint8_t brightness = lightSettings.brightness;
|
||||||
// Read ADC battery voltage and dimmer voltage
|
// Read ADC battery voltage and dimmer voltage
|
||||||
float v_bus = BSP_ADC_ReadBusValue() - DIMM_DEADZONE_VOLTAGE;
|
|
||||||
float v_dimm = BSP_ADC_ReadDimmerValue();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t dimm = 255;
|
||||||
|
|
||||||
|
// currenlty not working
|
||||||
|
// only dimm if the headlight is on
|
||||||
|
//if (Vehicle_isHeadlightOn()) {
|
||||||
|
|
||||||
|
// new version over CAN
|
||||||
|
//dimm = Vehicle_Brightness();
|
||||||
|
|
||||||
|
// old version over ADC
|
||||||
// calculate the dimmfactor based on the battery voltage and the dimmer voltage
|
// calculate the dimmfactor based on the battery voltage and the dimmer voltage
|
||||||
// the dimmfactor shoudl be 0 if the dimmer voltage is 4V.
|
// the dimmfactor shoudl be 0 if the dimmer voltage is 4V.
|
||||||
// the dimmfactor should be 1 if the dimmer voltage is the same as the battery voltage
|
// the dimmfactor should be 1 if the dimmer voltage is the same as the battery voltage
|
||||||
float dimmfactor;
|
// float v_bus = BSP_ADC_ReadBusValue() - DIMM_DEADZONE_VOLTAGE;
|
||||||
if (v_dimm >= v_bus) {
|
// float v_dimm = BSP_ADC_ReadDimmerValue();
|
||||||
dimmfactor = 1.0;
|
//if (v_dimm >= v_bus) {
|
||||||
} else if (v_dimm <= 4.0) {
|
// dimmfactor = 1.0;
|
||||||
dimmfactor = 0.0;
|
//} else if (v_dimm <= 4.0) {
|
||||||
} else {
|
// dimmfactor = 0.0;
|
||||||
dimmfactor = (v_dimm - 4.0) / (v_bus - 4.0);
|
//} else {
|
||||||
}
|
// dimmfactor = (v_dimm - 4.0) / (v_bus - 4.0);
|
||||||
|
//}
|
||||||
|
|
||||||
uint8_t adjustedBrightness = (uint8_t)(brightness * dimmfactor);
|
//}
|
||||||
|
|
||||||
|
uint8_t adjustedBrightness = (brightness * dimm)/ 255;
|
||||||
lightSettings_dimmed.brightness = adjustedBrightness;
|
lightSettings_dimmed.brightness = adjustedBrightness;
|
||||||
lightSettings_dimmed.theme = lightSettings.theme;
|
lightSettings_dimmed.theme = lightSettings.theme;
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ union {
|
|||||||
cls_light_ThemeSettings msg_cls_light_ThemeSettings;
|
cls_light_ThemeSettings msg_cls_light_ThemeSettings;
|
||||||
cls_light_SaveThemeSettings msg_cls_light_SaveThemeSettings;
|
cls_light_SaveThemeSettings msg_cls_light_SaveThemeSettings;
|
||||||
cls_light_RequestThemeSetting msg_cls_light_RequestThemeSetting;
|
cls_light_RequestThemeSetting msg_cls_light_RequestThemeSetting;
|
||||||
|
cls_usb_JumpToBootloader msg_cls_usb_JumpToBootloader;
|
||||||
|
|
||||||
} mem_msg_decode;
|
} mem_msg_decode;
|
||||||
|
|
||||||
@@ -119,6 +120,7 @@ message_handler_t message_handlers[] = {
|
|||||||
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_SETTING_THEME, cls_light_ThemeSettings),
|
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_SETTING_THEME, cls_light_ThemeSettings),
|
||||||
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_SETTING_THEME_SAVE, cls_light_SaveThemeSettings),
|
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_SETTING_THEME_SAVE, cls_light_SaveThemeSettings),
|
||||||
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_REQUEST_THEME, cls_light_RequestThemeSetting),
|
MESSAGE_HANDLER(cls_usb_PackageType_LIGHT_REQUEST_THEME, cls_light_RequestThemeSetting),
|
||||||
|
MESSAGE_HANDLER(cls_usb_PackageType_JUMP_TO_BOOTLOADER, cls_usb_JumpToBootloader),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ void UsbDataHandler_Runner();
|
|||||||
*/
|
*/
|
||||||
int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len);
|
int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len);
|
||||||
|
|
||||||
|
void DataClbk_cls_usb_JumpToBootloader(void* msg, uint32_t length);
|
||||||
|
|
||||||
void DataClbk_cls_firmware_Start(void* msg, uint32_t length);
|
void DataClbk_cls_firmware_Start(void* msg, uint32_t length);
|
||||||
void DataClbk_cls_firmware_Package(void* msg, uint32_t length);
|
void DataClbk_cls_firmware_Package(void* msg, uint32_t length);
|
||||||
|
|||||||
32
Application/Vehicle/CMakeLists.txt
Normal file
32
Application/Vehicle/CMakeLists.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Set the minimum required CMake version
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
# Set the project name
|
||||||
|
project(Vehicle)
|
||||||
|
|
||||||
|
# Add the source files for the library
|
||||||
|
set(SOURCES
|
||||||
|
Vehicle.c
|
||||||
|
Vehicle_can.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the header files for the library
|
||||||
|
set(HEADERS
|
||||||
|
Vehicle.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the library target
|
||||||
|
add_library(Vehicle ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
|
# Set the include directories for the library
|
||||||
|
target_include_directories(Vehicle PUBLIC ./)
|
||||||
|
|
||||||
|
# Set any additional compiler flags or options
|
||||||
|
# target_compile_options(Vehicle PRIVATE ...)
|
||||||
|
|
||||||
|
# Set any additional linker flags or options
|
||||||
|
# target_link_options(Vehicle PRIVATE ...)
|
||||||
|
|
||||||
|
# Specify any dependencies for the library
|
||||||
|
target_link_libraries(Vehicle BSP CLS CLS_BSP)
|
||||||
|
|
||||||
82
Application/Vehicle/Vehicle.c
Normal file
82
Application/Vehicle/Vehicle.c
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "BSP_GPIO.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "BSP_ADC.h"
|
||||||
|
|
||||||
|
// Define the threshold voltage for engine running
|
||||||
|
#define ENGINE_RUNNING_THRESHOLD 13.0 // 13.5V
|
||||||
|
|
||||||
|
// Define thresholds with hysteresis
|
||||||
|
#define ENGINE_RUNNING_THRESHOLD_HIGH (ENGINE_RUNNING_THRESHOLD + 0.225)
|
||||||
|
#define ENGINE_RUNNING_THRESHOLD_LOW (ENGINE_RUNNING_THRESHOLD - 0.225)
|
||||||
|
|
||||||
|
// Global variable to store the current engine state
|
||||||
|
static bool engineRunning = false;
|
||||||
|
|
||||||
|
|
||||||
|
void Vehicle_Init() {
|
||||||
|
engineRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vehicle_isHeadlightOn()
|
||||||
|
{
|
||||||
|
return BSP_GPIO_HeadLightIsSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vehicle_isEngineRunning() {
|
||||||
|
|
||||||
|
|
||||||
|
float voltage = BSP_ADC_ReadBusValue();
|
||||||
|
|
||||||
|
if (engineRunning)
|
||||||
|
{
|
||||||
|
// If engine is currently running, use the lower threshold to turn it off
|
||||||
|
if (voltage < ENGINE_RUNNING_THRESHOLD_LOW)
|
||||||
|
{
|
||||||
|
engineRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If engine is currently off, use the higher threshold to turn it on
|
||||||
|
if (voltage > ENGINE_RUNNING_THRESHOLD_HIGH)
|
||||||
|
{
|
||||||
|
engineRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return engineRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vehicle_isK15On() {
|
||||||
|
return BSP_GPIO_K15isSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "CLS.h"
|
||||||
|
#include "CLS_BSP.h"
|
||||||
|
#include "CLSAddress.h"
|
||||||
|
|
||||||
|
static CLS_VehicleStatus_t status = {0};
|
||||||
|
_Static_assert(sizeof(status) == 8, "CLS_HeatbeatData_t is not 8 bytes");
|
||||||
|
|
||||||
|
void CLS_VehicleHeatbeat(void *argument) {
|
||||||
|
CLS_BSP_TxHeaderType cls_vehicle_header = CREATE_BSP_CAN_HEADER(GENERATE_CLS_ADDRESS(CLS_CODE_STATUS,0,CLS_CH_STA_VEHICLE), CLS_BSP_DLC_BYTES_8);
|
||||||
|
|
||||||
|
|
||||||
|
status.k15 = Vehicle_isK15On();
|
||||||
|
status.headlight = Vehicle_isHeadlightOn();
|
||||||
|
status.engine = Vehicle_isEngineRunning();
|
||||||
|
status.speed = (uint8_t)Vehicle_Speed();
|
||||||
|
status.unlocked = Vehicle_UnlockedSignal();
|
||||||
|
|
||||||
|
CLS_BSP_CAN_AddMessageToSend(&cls_vehicle_header, (uint8_t*)&status);
|
||||||
|
|
||||||
|
}
|
||||||
24
Application/Vehicle/Vehicle.h
Normal file
24
Application/Vehicle/Vehicle.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
#include "fdcan.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
void Vehicle_Init();
|
||||||
|
|
||||||
|
bool Vehicle_isHeadlightOn();
|
||||||
|
|
||||||
|
bool Vehicle_isEngineRunning();
|
||||||
|
|
||||||
|
bool Vehicle_isK15On();
|
||||||
|
|
||||||
|
|
||||||
|
void Vehicle_Setup_CAN();
|
||||||
|
|
||||||
|
void Vehicle_Receive_CAN( FDCAN_RxHeaderTypeDef header, uint8_t* data);
|
||||||
|
|
||||||
|
|
||||||
|
bool Vehicle_gotUnlockMessage();
|
||||||
|
uint8_t Vehicle_Brightness();
|
||||||
|
float Vehicle_Speed();
|
||||||
|
int Vehicle_DirectionIsForward();
|
||||||
|
bool Vehicle_UnlockedSignal();
|
||||||
146
Application/Vehicle/Vehicle_can.c
Normal file
146
Application/Vehicle/Vehicle_can.c
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#include "Vehicle.h"
|
||||||
|
#include "fdcan.h"
|
||||||
|
#include "CLS.h"
|
||||||
|
#include "CLS_BSP.h"
|
||||||
|
#include "BSP_GPIO.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
static uint64_t last_unlock_message_time = UINT64_MAX;
|
||||||
|
static uint8_t car_can_brightness = 255;
|
||||||
|
static float car_can_speed = 0;
|
||||||
|
static int car_can_direction = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void Vehicle_Setup_CAN() {
|
||||||
|
|
||||||
|
|
||||||
|
FDCAN_FilterTypeDef sFilterConfig;
|
||||||
|
sFilterConfig.IdType = FDCAN_STANDARD_ID;
|
||||||
|
sFilterConfig.FilterIndex = 0;
|
||||||
|
sFilterConfig.FilterType = CLS_BSP_CAN_FILTER_LIST;
|
||||||
|
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
|
||||||
|
sFilterConfig.FilterID1 = 0x391;
|
||||||
|
sFilterConfig.FilterID2 = 0x395;
|
||||||
|
HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig);
|
||||||
|
|
||||||
|
sFilterConfig.FilterIndex = 1;
|
||||||
|
sFilterConfig.FilterID1 = 0x351;
|
||||||
|
sFilterConfig.FilterID2 = 0x635;
|
||||||
|
HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rx_unlock_key(uint8_t * RxData ) {
|
||||||
|
if (RxData[1] == 0x04)
|
||||||
|
{
|
||||||
|
// car was unlocked
|
||||||
|
last_unlock_message_time = osKernelGetTickCount();
|
||||||
|
}
|
||||||
|
else if (RxData[1] ==0x80)
|
||||||
|
{
|
||||||
|
// car was locked
|
||||||
|
if (!BSP_GPIO_K15isSet()) {
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_unlock_secure(uint8_t * RxData ) {
|
||||||
|
if ((RxData[0] & 0x0F) == 0x01) {
|
||||||
|
// car was unlocked
|
||||||
|
last_unlock_message_time = osKernelGetTickCount();
|
||||||
|
|
||||||
|
} else if ((RxData[0] & 0x0F) == 0x02) {
|
||||||
|
// car was locked
|
||||||
|
if (!BSP_GPIO_K15isSet()) {
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_speed(uint8_t * RxData) {
|
||||||
|
// speed signal
|
||||||
|
// AA BB XX YY 00 00 00 00
|
||||||
|
// Speed (XX*(2^8)+(YY-1))/190
|
||||||
|
// direction AA = 0x00 forward, 0x02 backward
|
||||||
|
uint16_t speed = (RxData[2] << 8) + RxData[3];
|
||||||
|
float speed_kmh = (speed - 1) / 190.0;
|
||||||
|
car_can_speed = speed_kmh;
|
||||||
|
car_can_direction = RxData[0];
|
||||||
|
//ULOG_DEBUG("Speed: %f, Direction: %d", car_can_speed, car_can_direction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_brightness(uint8_t* RxData) {
|
||||||
|
// scale the brightness to 0 - 255 only using integer math
|
||||||
|
car_can_brightness = ((uint32_t)RxData[0] * 255) / 100;
|
||||||
|
//ULOG_DEBUG("Brightness: %d", car_can_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vehicle_Receive_CAN( FDCAN_RxHeaderTypeDef RxHeader, uint8_t* RxData) {
|
||||||
|
|
||||||
|
if(RxHeader.Identifier == 0x391) {
|
||||||
|
rx_unlock_key(RxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RxHeader.Identifier == 0x395) {
|
||||||
|
rx_unlock_secure(RxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (RxHeader.Identifier == 0x351) {
|
||||||
|
rx_speed(RxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// brightness knob in 0 - 100
|
||||||
|
if (RxHeader.Identifier == 0x635) {
|
||||||
|
rx_brightness(RxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Vehicle_gotUnlockMessage() {
|
||||||
|
return last_unlock_message_time != UINT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Vehicle_Brightness() {
|
||||||
|
return car_can_brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Vehicle_Speed() {
|
||||||
|
return car_can_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Vehicle_DirectionIsForward() {
|
||||||
|
return car_can_direction == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool unlocked = false;
|
||||||
|
|
||||||
|
|
||||||
|
bool Vehicle_UnlockedSignal() {
|
||||||
|
|
||||||
|
if (unlocked) {
|
||||||
|
if(Vehicle_isK15On()) {
|
||||||
|
unlocked = false;
|
||||||
|
last_unlock_message_time = UINT64_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unlocked) {
|
||||||
|
if (Vehicle_gotUnlockMessage()) {
|
||||||
|
unlocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unlocked;
|
||||||
|
}
|
||||||
34
Application/ram_loader/CMakeLists.txt
Normal file
34
Application/ram_loader/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Set the minimum required CMake version
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
# Set the project name
|
||||||
|
project(ram_loader)
|
||||||
|
|
||||||
|
# Add the source files for the library
|
||||||
|
set(SOURCES
|
||||||
|
ram_loader.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the header files for the library
|
||||||
|
set(HEADERS
|
||||||
|
ram_loader.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the library target
|
||||||
|
add_library(ram_loader ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
|
# Set the include directories for the library
|
||||||
|
target_include_directories(ram_loader PUBLIC ./)
|
||||||
|
|
||||||
|
# Set any additional compiler flags or options
|
||||||
|
# target_compile_options(${PROJECT_NAME} PRIVATE ...)
|
||||||
|
|
||||||
|
# Set any additional linker flags or options
|
||||||
|
# target_link_options(${PROJECT_NAME} PRIVATE ...)
|
||||||
|
|
||||||
|
# Specify any dependencies for the library
|
||||||
|
# target_link_libraries(${PROJECT_NAME} <dependency1> <dependency2> ...)
|
||||||
|
|
||||||
|
# Optionally, add an executable target for testing
|
||||||
|
# add_executable(test_ram_loader test/test_ram_loader.cpp)
|
||||||
|
# target_link_libraries(test_ram_loader ${PROJECT_NAME})
|
||||||
110
Application/ram_loader/ram_loader.c
Normal file
110
Application/ram_loader/ram_loader.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include "fatfs.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#define RAM_LOADER_BUFFER_SIZE 15*1024
|
||||||
|
#define RAM_LOADER_ADDRESS 0x38000000
|
||||||
|
#define APP_START_ADDRESS RAM_LOADER_ADDRESS
|
||||||
|
uint8_t * ram_loader_buffer = (uint8_t *) RAM_LOADER_ADDRESS;
|
||||||
|
|
||||||
|
void _app_start(void)
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
// Reset USB
|
||||||
|
|
||||||
|
//De-init all peripherals
|
||||||
|
//HAL_ADC_DeInit(&hadc1);
|
||||||
|
|
||||||
|
// Disable Systick
|
||||||
|
SysTick->CTRL = 0;
|
||||||
|
SysTick->LOAD = 0;
|
||||||
|
SysTick->VAL = 0;
|
||||||
|
|
||||||
|
// Reset clock to default
|
||||||
|
HAL_RCC_DeInit();
|
||||||
|
|
||||||
|
// Clear all interrupt bits
|
||||||
|
for (uint8_t i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++)
|
||||||
|
{
|
||||||
|
NVIC->ICER[i] = 0xFFFFFFFF;
|
||||||
|
NVIC->ICPR[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
|
||||||
|
// set the vector table offset register
|
||||||
|
SCB->VTOR = APP_START_ADDRESS;
|
||||||
|
|
||||||
|
// get the application stack pointer
|
||||||
|
__set_MSP(((uint32_t *)APP_START_ADDRESS)[0]);
|
||||||
|
|
||||||
|
|
||||||
|
// jump to the application
|
||||||
|
((void (*)(void))((uint32_t *)APP_START_ADDRESS)[1])();
|
||||||
|
|
||||||
|
// the application should never return
|
||||||
|
// ULOG_ERROR("Failed to start application");
|
||||||
|
while (1) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t buffer[512];
|
||||||
|
|
||||||
|
void RamLoader_LoadApplication()
|
||||||
|
{
|
||||||
|
|
||||||
|
// check if the file "load.bin" exists
|
||||||
|
FIL file;
|
||||||
|
FRESULT res = f_open(&file, "load.bin", FA_READ);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
// ULOG_ERROR("Failed to open file load.bin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT size = f_size(&file);
|
||||||
|
// ensure the file is not larger than the buffer
|
||||||
|
if (size > RAM_LOADER_BUFFER_SIZE ) {
|
||||||
|
// ULOG_ERROR("File load.bin is too large");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the file into the buffer
|
||||||
|
UINT bytes_read;
|
||||||
|
uint32_t remaining_bytes = size;
|
||||||
|
uint8_t *destination_ptr = ram_loader_buffer;
|
||||||
|
uint8_t *buffer_ptr = buffer;
|
||||||
|
while (remaining_bytes > 0) {
|
||||||
|
UINT read_size = remaining_bytes > 512 ? 512 : remaining_bytes;
|
||||||
|
res = f_read(&file, buffer_ptr, read_size, &bytes_read);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
// ULOG_ERROR("Failed to read file load.bin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bytes_read != read_size) {
|
||||||
|
// ULOG_ERROR("Failed to read file load.bin completely");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(destination_ptr, buffer_ptr, read_size);
|
||||||
|
remaining_bytes -= read_size;
|
||||||
|
destination_ptr += read_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the file
|
||||||
|
f_close(&file);
|
||||||
|
|
||||||
|
|
||||||
|
// check that the file to flash exists ("firm.bin")
|
||||||
|
res = f_open(&file, "firm.bin", FA_READ);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
// ULOG_ERROR("Failed to open file firm.bin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//close the file
|
||||||
|
f_close(&file);
|
||||||
|
|
||||||
|
|
||||||
|
_app_start();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
3
Application/ram_loader/ram_loader.h
Normal file
3
Application/ram_loader/ram_loader.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void RamLoader_LoadApplication();
|
||||||
@@ -140,7 +140,7 @@ add_subdirectory("Application")
|
|||||||
add_executable(${CMAKE_PROJECT_NAME})
|
add_executable(${CMAKE_PROJECT_NAME})
|
||||||
target_sources(${CMAKE_PROJECT_NAME} PUBLIC ${sources_SRCS})
|
target_sources(${CMAKE_PROJECT_NAME} PUBLIC ${sources_SRCS})
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP BSP EE24 INA219 ulog)
|
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP BSP EE24 INA219 ulog ram_loader Vehicle)
|
||||||
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC PROTOS)
|
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC PROTOS)
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC uart_driver)
|
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC uart_driver)
|
||||||
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC lwrb)
|
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC lwrb)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#include "LightState.h"
|
#include "LightState.h"
|
||||||
#include "BSP_GPIO.h"
|
#include "BSP_GPIO.h"
|
||||||
#include "BSP_ADC.h"
|
#include "BSP_ADC.h"
|
||||||
|
#include "BSP_SDLogger.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -71,7 +73,7 @@ const osThreadAttr_t defaultTask_attributes = {
|
|||||||
osThreadId_t waitForStartConfirmHandle;
|
osThreadId_t waitForStartConfirmHandle;
|
||||||
const osThreadAttr_t waitForStartConfirm_attributes = {
|
const osThreadAttr_t waitForStartConfirm_attributes = {
|
||||||
.name = "waitForStartConfirm",
|
.name = "waitForStartConfirm",
|
||||||
.stack_size = 256 * 4,
|
.stack_size = 512 * 4,
|
||||||
.priority = (osPriority_t) osPriorityNormal,
|
.priority = (osPriority_t) osPriorityNormal,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,6 +188,8 @@ void StartDefaultTask(void *argument)
|
|||||||
ULOG_INFO(output);
|
ULOG_INFO(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BSP_SDLogger_Init(counter);
|
||||||
|
|
||||||
char INA_LOG[72];
|
char INA_LOG[72];
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
@@ -233,7 +237,7 @@ void WaitForStartConfirm_Task(void *argument) {
|
|||||||
while(1) {
|
while(1) {
|
||||||
osDelayUntil(tick);
|
osDelayUntil(tick);
|
||||||
tick += delayTime;
|
tick += delayTime;
|
||||||
if(BSP_GPIO_K15isSet() || CanDataTask_gotCarCanMessage()) {
|
if(BSP_GPIO_K15isSet() || Vehicle_gotUnlockMessage()) {
|
||||||
BSP_POWER_FullPowerMode();
|
BSP_POWER_FullPowerMode();
|
||||||
ULOG_INFO("Power systems started");
|
ULOG_INFO("Power systems started");
|
||||||
osThreadExit();
|
osThreadExit();
|
||||||
@@ -247,13 +251,13 @@ void WaitForStartConfirm_Task(void *argument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(tick > maxDelayTime) {
|
if(tick > maxDelayTime) {
|
||||||
BSP_POWER_EnterStandby();
|
|
||||||
ULOG_INFO("System in standby mode");
|
|
||||||
osThreadExit();
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
osDelay(1000);
|
ULOG_INFO("System in standby mode");
|
||||||
|
BSP_POWER_EnterStandby();
|
||||||
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
osThreadExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "BSP_POWER.h"
|
#include "BSP_POWER.h"
|
||||||
#include "BSP_GPIO.h"
|
#include "BSP_GPIO.h"
|
||||||
#include "BSP_ADC.h"
|
#include "BSP_ADC.h"
|
||||||
|
#include "ram_loader.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
// define the magic number for the bootloader 8 bytes
|
||||||
/* USER CODE BEGIN PV */
|
/* USER CODE BEGIN PV */
|
||||||
uint8_t gCLS_DEVICE_ADDRESS = 0x11;
|
uint8_t gCLS_DEVICE_ADDRESS = 0x11;
|
||||||
/* USER CODE END PV */
|
/* USER CODE END PV */
|
||||||
@@ -72,6 +74,7 @@ static void MPU_Config(void);
|
|||||||
void MX_FREERTOS_Init(void);
|
void MX_FREERTOS_Init(void);
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
void ULOG_SendLPUART(ulog_level_t level, char *msg);
|
void ULOG_SendLPUART(ulog_level_t level, char *msg);
|
||||||
|
|
||||||
/* USER CODE END PFP */
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
@@ -87,6 +90,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* Enable I-Cache---------------------------------------------------------*/
|
/* Enable I-Cache---------------------------------------------------------*/
|
||||||
@@ -285,6 +289,9 @@ void ULOG_SendLPUART(ulog_level_t level, char *msg) {
|
|||||||
HAL_UART_Transmit(&hlpuart1, (const uint8_t*)ulog_send_buffer, send_length, LOG_TIMEOUT);
|
HAL_UART_Transmit(&hlpuart1, (const uint8_t*)ulog_send_buffer, send_length, LOG_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataClbk_cls_usb_JumpToBootloader(void* msg, uint32_t length) {
|
||||||
|
RamLoader_LoadApplication();
|
||||||
|
}
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
/* MPU Configuration */
|
/* MPU Configuration */
|
||||||
|
|||||||
@@ -99,6 +99,21 @@ void HardFault_Handler(void)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||||
|
|
||||||
|
HAL_GPIO_TogglePin(DIO12_L2_GPIO_Port, DIO12_L2_Pin);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 10000000; i++)
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,6 +129,18 @@ void MemManage_Handler(void)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||||
|
HAL_GPIO_TogglePin(DIO12_L2_GPIO_Port, DIO12_L2_Pin);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 30000000; i++)
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,9 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
|
|||||||
/* Specify the memory areas */
|
/* Specify the memory areas */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
RAM_EXEC (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
|
RAM_EXEC (xrw) : ORIGIN = 0x24000000, LENGTH = 319K
|
||||||
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
RAM_NOINIT(xrw) : ORIGIN = 0x2404fc00, LENGTH = 1K
|
||||||
|
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 127K
|
||||||
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||||
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
|
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
|
||||||
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
|
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||||
@@ -161,6 +162,12 @@ SECTIONS
|
|||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
} >DTCMRAM
|
} >DTCMRAM
|
||||||
|
|
||||||
|
|
||||||
|
.noinit :
|
||||||
|
{
|
||||||
|
KEEP(*(.noinitdata))
|
||||||
|
} >DTCMRAM2
|
||||||
|
|
||||||
/* Remove information from the standard libraries */
|
/* Remove information from the standard libraries */
|
||||||
/DISCARD/ :
|
/DISCARD/ :
|
||||||
{
|
{
|
||||||
|
|||||||
2
proto
2
proto
Submodule proto updated: 30e74889a2...4ff29f9d5b
13
tools/bootloader.py
Normal file
13
tools/bootloader.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from usb_pb2 import PackageType, JumpToBootloader
|
||||||
|
from vcp_driver import *
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ser = setup_connection()
|
||||||
|
# Create a message
|
||||||
|
request = JumpToBootloader()
|
||||||
|
request.magic = 0xdeadbeef
|
||||||
|
# Serialize the request to a bytearray
|
||||||
|
request_data = request.SerializeToString()
|
||||||
|
|
||||||
|
# Send the request
|
||||||
|
send_package(PackageType.JUMP_TO_BOOTLOADER, request_data, ser)
|
||||||
@@ -30,7 +30,7 @@ def make_header(typeid: PackageType, length: int) -> bytearray:
|
|||||||
struct_format = '<HHB' # '<' for little-endian, 'H' for uint16_t, 'B' for uint8_t
|
struct_format = '<HHB' # '<' for little-endian, 'H' for uint16_t, 'B' for uint8_t
|
||||||
# Calculate the check byte as the sum of length and type
|
# Calculate the check byte as the sum of length and type
|
||||||
typeidint = int(typeid)
|
typeidint = int(typeid)
|
||||||
check = (length & 0xFF) + ((length >> 8) & 0xFF) + (typeidint & 0xFF) + ((typeidint >> 8) & 0xFF)
|
check = ((length & 0xFF) + ((length >> 8) & 0xFF) + (typeidint & 0xFF) + ((typeidint >> 8) & 0xFF) ) & 0xff
|
||||||
packed_data = struct.pack(struct_format, length, typeid, check)
|
packed_data = struct.pack(struct_format, length, typeid, check)
|
||||||
return packed_data
|
return packed_data
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ if __name__ == "__main__":
|
|||||||
ser = setup_connection()
|
ser = setup_connection()
|
||||||
# Create a message
|
# Create a message
|
||||||
request = UpdateDeviceSettings()
|
request = UpdateDeviceSettings()
|
||||||
request.device = 1
|
request.device = 0
|
||||||
request.type = Type.LIGHT
|
request.type = Type.COMMING_HOME
|
||||||
request.position.append(Position.RIGHT)
|
request.position.append(Position.LEFT)
|
||||||
request.position.append(Position.FLOOR)
|
request.position.append(Position.CENTER)
|
||||||
# Serialize the request to a bytearray
|
# Serialize the request to a bytearray
|
||||||
request_data = request.SerializeToString()
|
request_data = request.SerializeToString()
|
||||||
|
|
||||||
|
|||||||
71
tools/upload_firmware.py
Normal file
71
tools/upload_firmware.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
import requests
|
||||||
|
import subprocess
|
||||||
|
import base64
|
||||||
|
|
||||||
|
def load_secret_key(keyb64: str):
|
||||||
|
# Decode the base64 encoded key
|
||||||
|
decoded_key = base64.b64decode(keyb64)
|
||||||
|
|
||||||
|
return decoded_key
|
||||||
|
|
||||||
|
def compute_hmac(file_path, secret_key):
|
||||||
|
"""Compute the HMAC of a file using HMAC-SHA256."""
|
||||||
|
hmac_obj = hmac.new(secret_key, digestmod=hashlib.sha256)
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
while chunk := f.read(4096):
|
||||||
|
hmac_obj.update(chunk)
|
||||||
|
return hmac_obj.hexdigest()
|
||||||
|
|
||||||
|
def upload_file(url, file_path, secret_key):
|
||||||
|
"""Upload a file to the server with an HMAC signature."""
|
||||||
|
# Compute HMAC of the file
|
||||||
|
signature = compute_hmac(file_path, secret_key)
|
||||||
|
print(signature)
|
||||||
|
# Prepare headers
|
||||||
|
headers = {'X-Signature': signature}
|
||||||
|
|
||||||
|
# Read file and prepare files dictionary for request
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
files = {'file': (Path(file_path).name, f)}
|
||||||
|
response = requests.post(url, files=files, headers=headers)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def get_short_git_commit_hash():
|
||||||
|
try:
|
||||||
|
# Run the Git command to get the short commit hash
|
||||||
|
result = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True)
|
||||||
|
# Extract and return the commit hash
|
||||||
|
return result.stdout.strip()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error getting Git commit hash: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
url = "https://fw.revwal.de/master/upload" # Adjust this to your server's URL
|
||||||
|
|
||||||
|
|
||||||
|
fw_path = "build/CLS_Master.bin" # Path to the file you want to upload
|
||||||
|
|
||||||
|
# Get the Git commit hash
|
||||||
|
commit_hash = get_short_git_commit_hash()
|
||||||
|
if commit_hash is None:
|
||||||
|
print("Error: Could not get Git commit hash")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# replace the file name with the commit hash
|
||||||
|
file_path = fw_path.replace("CLS_Master", commit_hash)
|
||||||
|
|
||||||
|
# copy the file to the new name
|
||||||
|
subprocess.run(['cp', fw_path, file_path])
|
||||||
|
|
||||||
|
|
||||||
|
secret_key = load_secret_key(sys.argv[1])
|
||||||
|
|
||||||
|
response = upload_file(url, file_path, secret_key)
|
||||||
|
print(f"Server response: {response.text}")
|
||||||
Reference in New Issue
Block a user