From bc7a779632764b607b3da75284d7d6d687bff7be Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Fri, 8 May 2015 22:53:59 +0200 Subject: [PATCH] Bootloader support, CAN fixes --- Makefile | 3 +- comm_can.c | 100 +++++++++++++++++++------------ commands.c | 31 +++++++++- conf_general.h | 4 +- datatypes.h | 3 + eeprom.h | 8 +-- flash_helper.c | 130 +++++++++++++++++++++++++++++++++++++++++ flash_helper.h | 34 +++++++++++ hwconf/hw_40.h | 8 +-- hwconf/hw_45.h | 8 +-- hwconf/hw_46.h | 8 +-- hwconf/hw_bw.h | 8 +-- hwconf/hw_r2.h | 8 +-- hwconf/hw_victor_r1a.h | 8 +-- ld_eeprom_emu.ld | 2 +- ledpwm.c | 8 +-- main.c | 2 +- utils.c | 42 +++++++++++++ utils.h | 1 + 19 files changed, 340 insertions(+), 76 deletions(-) create mode 100644 flash_helper.c create mode 100644 flash_helper.h diff --git a/Makefile b/Makefile index 526d1e9c..e52dc7cb 100644 --- a/Makefile +++ b/Makefile @@ -118,6 +118,7 @@ CSRC = $(PORTSRC) \ ws2811.c \ led_external.c \ encoder.c \ + flash_helper.c \ $(HWSRC) \ $(APPSRC) \ $(NRFSRC) @@ -277,5 +278,3 @@ upload: build/$(PROJECT).bin debug-start: openocd -f stm32-bv_openocd.cfg - - diff --git a/comm_can.c b/comm_can.c index 5765a27e..e563b9ac 100644 --- a/comm_can.c +++ b/comm_can.c @@ -36,18 +36,25 @@ // Settings #define CANDx CAND1 +#define RX_FRAMES_SIZE 10 // Threads -static WORKING_AREA(cancom_thread_wa, 4096); +static WORKING_AREA(cancom_read_thread_wa, 512); +static WORKING_AREA(cancom_process_thread_wa, 4096); static WORKING_AREA(cancom_status_thread_wa, 1024); -static msg_t cancom_thread(void *arg); +static msg_t cancom_read_thread(void *arg); static msg_t cancom_status_thread(void *arg); +static msg_t cancom_process_thread(void *arg); // Variables static can_status_msg stat_msgs[CAN_STATUS_MSGS_TO_STORE]; static Mutex can_mtx; static uint8_t rx_buffer[256]; static uint8_t rx_buffer_last_id; +static CANRxFrame rx_frames[RX_FRAMES_SIZE]; +static int rx_frame_read; +static int rx_frame_write; +static Thread *process_tp; /* * 500KBaud, automatic wakeup, automatic recover @@ -68,6 +75,9 @@ void comm_can_init(void) { stat_msgs[i].id = -1; } + rx_frame_read = 0; + rx_frame_write = 0; + chMtxInit(&can_mtx); palSetPadMode(GPIOB, 8, @@ -79,27 +89,22 @@ void comm_can_init(void) { PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_MID1); - chMtxLock(&can_mtx); canStart(&CANDx, &cancfg); - chMtxUnlock(); - chThdCreateStatic(cancom_thread_wa, sizeof(cancom_thread_wa), NORMALPRIO, - cancom_thread, NULL); + chThdCreateStatic(cancom_read_thread_wa, sizeof(cancom_read_thread_wa), NORMALPRIO + 1, + cancom_read_thread, NULL); chThdCreateStatic(cancom_status_thread_wa, sizeof(cancom_status_thread_wa), NORMALPRIO, cancom_status_thread, NULL); + chThdCreateStatic(cancom_process_thread_wa, sizeof(cancom_process_thread_wa), NORMALPRIO, + cancom_process_thread, NULL); } -static msg_t cancom_thread(void *arg) { +static msg_t cancom_read_thread(void *arg) { (void)arg; chRegSetThreadName("CAN"); EventListener el; CANRxFrame rxmsg; - int32_t ind = 0; - int32_t rxbuf_len; - uint8_t crc_low; - uint8_t crc_high; - bool commands_send; chEvtRegister(&CANDx.rxfull_event, &el, 0); @@ -108,11 +113,42 @@ static msg_t cancom_thread(void *arg) { continue; } - chMtxLock(&can_mtx); msg_t result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE); - chMtxUnlock(); while (result == RDY_OK) { + rx_frames[rx_frame_write++] = rxmsg; + if (rx_frame_write == RX_FRAMES_SIZE) { + rx_frame_write = 0; + } + + chEvtSignal(process_tp, (eventmask_t) 1); + + result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE); + } + } + + chEvtUnregister(&CANDx.rxfull_event, &el); + return 0; +} + +static msg_t cancom_process_thread(void *arg) { + (void)arg; + + chRegSetThreadName("Cancom process"); + process_tp = chThdSelf(); + + int32_t ind = 0; + int32_t rxbuf_len; + uint8_t crc_low; + uint8_t crc_high; + bool commands_send; + + for(;;) { + chEvtWaitAny((eventmask_t) 1); + + while (rx_frame_read != rx_frame_write) { + CANRxFrame rxmsg = rx_frames[rx_frame_read++]; + if (rxmsg.IDE == CAN_IDE_EXT) { uint8_t id = rxmsg.EID & 0xFF; CAN_PACKET_ID cmd = rxmsg.EID >> 8; @@ -214,13 +250,12 @@ static msg_t cancom_thread(void *arg) { } } - chMtxLock(&can_mtx); - result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE); - chMtxUnlock(); + if (rx_frame_read == RX_FRAMES_SIZE) { + rx_frame_read = 0; + } } } - chEvtUnregister(&CAND1.rxfull_event, &el); return 0; } @@ -252,26 +287,17 @@ static msg_t cancom_status_thread(void *arg) { void comm_can_transmit(uint32_t id, uint8_t *data, uint8_t len) { #if CAN_ENABLE + CANTxFrame txmsg; + txmsg.IDE = CAN_IDE_EXT; + txmsg.EID = id; + txmsg.RTR = CAN_RTR_DATA; + txmsg.DLC = len; + memcpy(txmsg.data8, data, len); + chMtxLock(&can_mtx); - - static CANTxFrame txmsg[10]; - static int txmsg_ind = 0; - - txmsg[txmsg_ind].IDE = CAN_IDE_EXT; - txmsg[txmsg_ind].EID = id; - txmsg[txmsg_ind].RTR = CAN_RTR_DATA; - txmsg[txmsg_ind].DLC = len; - - memcpy(txmsg[txmsg_ind].data8, data, len); - - canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg[txmsg_ind], MS2ST(50)); - - txmsg_ind++; - if (txmsg_ind >= 10) { - txmsg_ind = 0; - } - + canTransmit(&CANDx, CAN_ANY_MAILBOX, &txmsg, MS2ST(20)); chMtxUnlock(); + #else (void)id; (void)data; @@ -331,7 +357,7 @@ void comm_can_send_buffer(uint8_t controller_id, uint8_t *data, uint8_t len, boo send_buffer[ind++] = (uint8_t)(crc >> 8); send_buffer[ind++] = (uint8_t)(crc & 0xFF); - comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_PROCESS_RX_BUFFER << 8), send_buffer, 5); + comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_PROCESS_RX_BUFFER << 8), send_buffer, ind++); } } diff --git a/commands.c b/commands.c index b9e204fa..31c1e8ed 100644 --- a/commands.c +++ b/commands.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2014 Benjamin Vedder benjamin@vedder.se + Copyright 2012-2015 Benjamin Vedder benjamin@vedder.se This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,6 +37,8 @@ #include "timeout.h" #include "servo_dec.h" #include "comm_can.h" +#include "flash_helper.h" +#include "utils.h" #include #include @@ -107,6 +109,8 @@ void commands_process_packet(unsigned char *data, unsigned char len) { bool at_start; mc_configuration mcconf; app_configuration appconf; + uint16_t flash_res; + uint32_t new_app_offset; (void)len; @@ -123,6 +127,31 @@ void commands_process_packet(unsigned char *data, unsigned char len) { commands_send_packet(send_buffer, ind); break; + case COMM_JUMP_TO_BOOTLOADER: + utils_jump_to_bootloader(); + break; + + case COMM_ERASE_NEW_APP: + ind = 0; + flash_res = flash_helper_erase_new_app(buffer_get_uint32(data, &ind)); + + ind = 0; + send_buffer[ind++] = COMM_ERASE_NEW_APP; + send_buffer[ind++] = flash_res == FLASH_COMPLETE ? 1 : 0; + commands_send_packet(send_buffer, ind); + break; + + case COMM_WRITE_NEW_APP_DATA: + ind = 0; + new_app_offset = buffer_get_uint32(data, &ind); + flash_res = flash_helper_write_new_app_data(new_app_offset, data + ind, len - ind); + + ind = 0; + send_buffer[ind++] = COMM_WRITE_NEW_APP_DATA; + send_buffer[ind++] = flash_res == FLASH_COMPLETE ? 1 : 0; + commands_send_packet(send_buffer, ind); + break; + case COMM_GET_VALUES: ind = 0; send_buffer[ind++] = COMM_GET_VALUES; diff --git a/conf_general.h b/conf_general.h index 82421d72..339afa06 100644 --- a/conf_general.h +++ b/conf_general.h @@ -25,9 +25,9 @@ #ifndef CONF_GENERAL_H_ #define CONF_GENERAL_H_ -// Software version +// Firmware version #define FW_VERSION_MAJOR 1 -#define FW_VERSION_MINOR 0 +#define FW_VERSION_MINOR 1 #include "datatypes.h" diff --git a/datatypes.h b/datatypes.h index a7c616ee..6f6a783c 100644 --- a/datatypes.h +++ b/datatypes.h @@ -257,6 +257,9 @@ typedef struct { // Communication commands typedef enum { COMM_FW_VERSION = 0, + COMM_JUMP_TO_BOOTLOADER, + COMM_ERASE_NEW_APP, + COMM_WRITE_NEW_APP_DATA, COMM_GET_VALUES, COMM_SET_DUTY, COMM_SET_CURRENT, diff --git a/eeprom.h b/eeprom.h index 6a5e8c7d..f1a233d8 100644 --- a/eeprom.h +++ b/eeprom.h @@ -36,18 +36,18 @@ #define VOLTAGE_RANGE (uint8_t)VoltageRange_3 /* EEPROM start address in Flash */ -#define EEPROM_START_ADDRESS ((uint32_t)0x08008000) /* EEPROM emulation start address: - from sector2 : after 16KByte of used +#define EEPROM_START_ADDRESS ((uint32_t)0x08004000) /* EEPROM emulation start address: + from sector1 : after 16KByte of used Flash memory */ /* Pages 0 and 1 base and end addresses */ #define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000)) #define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1))) -#define PAGE0_ID FLASH_Sector_2 +#define PAGE0_ID FLASH_Sector_1 #define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x4000)) #define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1))) -#define PAGE1_ID FLASH_Sector_3 +#define PAGE1_ID FLASH_Sector_2 /* Used Flash pages for EEPROM emulation */ #define PAGE0 ((uint16_t)0x0000) diff --git a/flash_helper.c b/flash_helper.c new file mode 100644 index 00000000..d0de47a3 --- /dev/null +++ b/flash_helper.c @@ -0,0 +1,130 @@ +/* + Copyright 2012-2015 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * flash_helper.c + * + * Created on: 6 maj 2015 + * Author: benjamin + */ + +#include "flash_helper.h" +#include "ch.h" +#include "hal.h" +#include "stm32f4xx_conf.h" +#include "utils.h" +#include + +/* + * Defines + */ +#define FLASH_SECTORS 12 +#define BOOTLOADER_BASE 11 +#define APP_BASE 0 +#define NEW_APP_BASE 8 +#define NEW_APP_SECTORS 3 + +// Base address of the Flash sectors +#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) // Base @ of Sector 0, 16 Kbytes +#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) // Base @ of Sector 1, 16 Kbytes +#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) // Base @ of Sector 2, 16 Kbytes +#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) // Base @ of Sector 3, 16 Kbytes +#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) // Base @ of Sector 4, 64 Kbytes +#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) // Base @ of Sector 5, 128 Kbytes +#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) // Base @ of Sector 6, 128 Kbytes +#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) // Base @ of Sector 7, 128 Kbytes +#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) // Base @ of Sector 8, 128 Kbytes +#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) // Base @ of Sector 9, 128 Kbytes +#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) // Base @ of Sector 10, 128 Kbytes +#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) // Base @ of Sector 11, 128 Kbytes + +// Private constants +static const uint32_t flash_addr[FLASH_SECTORS] = { + ADDR_FLASH_SECTOR_0, + ADDR_FLASH_SECTOR_1, + ADDR_FLASH_SECTOR_2, + ADDR_FLASH_SECTOR_3, + ADDR_FLASH_SECTOR_4, + ADDR_FLASH_SECTOR_5, + ADDR_FLASH_SECTOR_6, + ADDR_FLASH_SECTOR_7, + ADDR_FLASH_SECTOR_8, + ADDR_FLASH_SECTOR_9, + ADDR_FLASH_SECTOR_10, + ADDR_FLASH_SECTOR_11 +}; +static const uint16_t flash_sector[12] = { + FLASH_Sector_0, + FLASH_Sector_1, + FLASH_Sector_2, + FLASH_Sector_3, + FLASH_Sector_4, + FLASH_Sector_5, + FLASH_Sector_6, + FLASH_Sector_7, + FLASH_Sector_8, + FLASH_Sector_9, + FLASH_Sector_10, + FLASH_Sector_11 +}; + +uint16_t flash_helper_erase_new_app(uint32_t new_app_size) { + FLASH_Unlock(); + FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | + FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); + + new_app_size += flash_addr[NEW_APP_BASE]; + + utils_sys_lock_cnt(); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); + + for (int i = 0;i < NEW_APP_SECTORS;i++) { + if (new_app_size > flash_addr[NEW_APP_BASE + i]) { + uint16_t res = FLASH_EraseSector(flash_sector[NEW_APP_BASE + i], VoltageRange_3); + if (res != FLASH_COMPLETE) { + return res; + } + } else { + break; + } + } + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); + utils_sys_unlock_cnt(); + + return FLASH_COMPLETE; +} + +uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len) { + FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | + FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); + + utils_sys_lock_cnt(); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); + + for (uint32_t i = 0;i < len;i++) { + uint16_t res = FLASH_ProgramByte(flash_addr[NEW_APP_BASE] + offset + i, data[i]); + if (res != FLASH_COMPLETE) { + return res; + } + } + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); + utils_sys_unlock_cnt(); + + return FLASH_COMPLETE; +} diff --git a/flash_helper.h b/flash_helper.h new file mode 100644 index 00000000..06deac1b --- /dev/null +++ b/flash_helper.h @@ -0,0 +1,34 @@ +/* + Copyright 2012-2015 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * flash_helper.h + * + * Created on: 6 maj 2015 + * Author: benjamin + */ + +#ifndef FLASH_HELPER_H_ +#define FLASH_HELPER_H_ + +#include "conf_general.h" + +// Functions +uint16_t flash_helper_erase_new_app(uint32_t new_app_size); +uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len); + +#endif /* FLASH_HELPER_H_ */ diff --git a/hwconf/hw_40.h b/hwconf/hw_40.h index 4a91ad02..e3d163d9 100644 --- a/hwconf/hw_40.h +++ b/hwconf/hw_40.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOC, 4) -#define LED1_OFF() palClearPad(GPIOC, 4) -#define LED2_ON() palSetPad(GPIOA, 7) -#define LED2_OFF() palClearPad(GPIOA, 7) +#define LED_GREEN_ON() palSetPad(GPIOC, 4) +#define LED_GREEN_OFF() palClearPad(GPIOC, 4) +#define LED_RED_ON() palSetPad(GPIOA, 7) +#define LED_RED_OFF() palClearPad(GPIOA, 7) /* * ADC Vector diff --git a/hwconf/hw_45.h b/hwconf/hw_45.h index 55b244f5..924d520f 100644 --- a/hwconf/hw_45.h +++ b/hwconf/hw_45.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOC, 4) -#define LED1_OFF() palClearPad(GPIOC, 4) -#define LED2_ON() palSetPad(GPIOA, 7) -#define LED2_OFF() palClearPad(GPIOA, 7) +#define LED_GREEN_ON() palSetPad(GPIOC, 4) +#define LED_GREEN_OFF() palClearPad(GPIOC, 4) +#define LED_RED_ON() palSetPad(GPIOA, 7) +#define LED_RED_OFF() palClearPad(GPIOA, 7) /* * ADC Vector diff --git a/hwconf/hw_46.h b/hwconf/hw_46.h index 4ee13bee..3011c148 100644 --- a/hwconf/hw_46.h +++ b/hwconf/hw_46.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOC, 4) -#define LED1_OFF() palClearPad(GPIOC, 4) -#define LED2_ON() palSetPad(GPIOA, 7) -#define LED2_OFF() palClearPad(GPIOA, 7) +#define LED_GREEN_ON() palSetPad(GPIOC, 4) +#define LED_GREEN_OFF() palClearPad(GPIOC, 4) +#define LED_RED_ON() palSetPad(GPIOA, 7) +#define LED_RED_OFF() palClearPad(GPIOA, 7) /* * ADC Vector diff --git a/hwconf/hw_bw.h b/hwconf/hw_bw.h index e39c1fa6..d0aa68d0 100644 --- a/hwconf/hw_bw.h +++ b/hwconf/hw_bw.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOC, 4) -#define LED1_OFF() palClearPad(GPIOC, 4) -#define LED2_ON() palSetPad(GPIOA, 7) -#define LED2_OFF() palClearPad(GPIOA, 7) +#define LED_GREEN_ON() palSetPad(GPIOC, 4) +#define LED_GREEN_OFF() palClearPad(GPIOC, 4) +#define LED_RED_ON() palSetPad(GPIOA, 7) +#define LED_RED_OFF() palClearPad(GPIOA, 7) /* * ADC Vector diff --git a/hwconf/hw_r2.h b/hwconf/hw_r2.h index d848a615..2d24c4e7 100644 --- a/hwconf/hw_r2.h +++ b/hwconf/hw_r2.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOB, 6) -#define LED1_OFF() palClearPad(GPIOB, 6) -#define LED2_ON() palSetPad(GPIOB, 7) -#define LED2_OFF() palClearPad(GPIOB, 7) +#define LED_GREEN_ON() palSetPad(GPIOB, 6) +#define LED_GREEN_OFF() palClearPad(GPIOB, 6) +#define LED_RED_ON() palSetPad(GPIOB, 7) +#define LED_RED_OFF() palClearPad(GPIOB, 7) /* * ADC Vector diff --git a/hwconf/hw_victor_r1a.h b/hwconf/hw_victor_r1a.h index dc7e0003..d87ebca3 100644 --- a/hwconf/hw_victor_r1a.h +++ b/hwconf/hw_victor_r1a.h @@ -32,10 +32,10 @@ #define DCCAL_OFF() palClearPad(GPIOB, 12) #define IS_DRV_FAULT() (!palReadPad(GPIOC, 12)) -#define LED1_ON() palSetPad(GPIOC, 4) -#define LED1_OFF() palClearPad(GPIOC, 4) -#define LED2_ON() palSetPad(GPIOA, 7) -#define LED2_OFF() palClearPad(GPIOA, 7) +#define LED_GREEN_ON() palSetPad(GPIOC, 4) +#define LED_GREEN_OFF() palClearPad(GPIOC, 4) +#define LED_RED_ON() palSetPad(GPIOA, 7) +#define LED_RED_OFF() palClearPad(GPIOA, 7) /* * ADC Vector diff --git a/ld_eeprom_emu.ld b/ld_eeprom_emu.ld index 0a3be393..efac0cf2 100644 --- a/ld_eeprom_emu.ld +++ b/ld_eeprom_emu.ld @@ -27,7 +27,7 @@ __process_stack_size__ = 0x0800; MEMORY { flash : org = 0x08000000, len = 16k - flash2 : org = 0x08020000, len = 896k + flash2 : org = 0x0800C000, len = 480k ram : org = 0x20000000, len = 128k ccmram : org = 0x10000000, len = 64k } diff --git a/ledpwm.c b/ledpwm.c index a71d8428..a2daea98 100644 --- a/ledpwm.c +++ b/ledpwm.c @@ -91,14 +91,14 @@ void ledpwm_update_pwm(void) { } if (cnt >= led_values[0]) { - LED1_OFF(); + LED_GREEN_OFF(); } else { - LED1_ON(); + LED_GREEN_ON(); } if (cnt >= led_values[1]) { - LED2_OFF(); + LED_RED_OFF(); } else { - LED2_ON(); + LED_RED_ON(); } } diff --git a/main.c b/main.c index 72a6a834..6ce2bfa5 100644 --- a/main.c +++ b/main.c @@ -340,6 +340,6 @@ int main(void) { chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL); for(;;) { - chThdSleepMilliseconds(100); + chThdSleepMilliseconds(5000); } } diff --git a/utils.c b/utils.c index 1f44c13d..1feff78b 100644 --- a/utils.c +++ b/utils.c @@ -24,6 +24,8 @@ #include "utils.h" #include "ch.h" +#include "hal.h" +#include "mcpwm.h" #include // Private variables @@ -150,4 +152,44 @@ void utils_sys_unlock_cnt(void) { } } +/** + * Stop the system and jump to the bootloader. + */ +void utils_jump_to_bootloader(void) { + typedef void (*pFunction)(void); + mcpwm_release_motor(); + usbDisconnectBus(&USBD1); + usbStop(&USBD1); + + // Disable watchdog + RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE); + + chSysDisable(); + + pFunction jump_to_bootloader; + + // Variable that will be loaded with the start address of the application + vu32* jump_address; + const vu32* bootloader_address = (vu32*)0x080E0000; + + // Get jump address from application vector table + jump_address = (vu32*) bootloader_address[1]; + + // Load this address into function pointer + jump_to_bootloader = (pFunction) jump_address; + + // Clear pending interrupts + SCB_ICSR = ICSR_PENDSVCLR; + + // Disable all interrupts + for(int i = 0;i < 8;i++) { + NVIC->ICER[i] = NVIC->IABR[i]; + } + + // Set stack pointer + __set_MSP((u32) (bootloader_address[0])); + + // Jump to the bootloader + jump_to_bootloader(); +} diff --git a/utils.h b/utils.h index e99b053e..d47bcfc5 100644 --- a/utils.h +++ b/utils.h @@ -34,6 +34,7 @@ void utils_deadband(float *value, float tres, float max); float utils_angle_difference(float angle1, float angle2); void utils_sys_lock_cnt(void); void utils_sys_unlock_cnt(void); +void utils_jump_to_bootloader(void); // Return the sign of the argument. -1 if negative, 1 if zero or positive. #define SIGN(x) ((x<0)?-1:1)