mirror of https://github.com/rusefi/bldc.git
Bootloader support, CAN fixes
This commit is contained in:
parent
5a5ccfb4c3
commit
bc7a779632
3
Makefile
3
Makefile
|
@ -118,6 +118,7 @@ CSRC = $(PORTSRC) \
|
||||||
ws2811.c \
|
ws2811.c \
|
||||||
led_external.c \
|
led_external.c \
|
||||||
encoder.c \
|
encoder.c \
|
||||||
|
flash_helper.c \
|
||||||
$(HWSRC) \
|
$(HWSRC) \
|
||||||
$(APPSRC) \
|
$(APPSRC) \
|
||||||
$(NRFSRC)
|
$(NRFSRC)
|
||||||
|
@ -277,5 +278,3 @@ upload: build/$(PROJECT).bin
|
||||||
|
|
||||||
debug-start:
|
debug-start:
|
||||||
openocd -f stm32-bv_openocd.cfg
|
openocd -f stm32-bv_openocd.cfg
|
||||||
|
|
||||||
|
|
||||||
|
|
100
comm_can.c
100
comm_can.c
|
@ -36,18 +36,25 @@
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
#define CANDx CAND1
|
#define CANDx CAND1
|
||||||
|
#define RX_FRAMES_SIZE 10
|
||||||
|
|
||||||
// Threads
|
// 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 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_status_thread(void *arg);
|
||||||
|
static msg_t cancom_process_thread(void *arg);
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
static can_status_msg stat_msgs[CAN_STATUS_MSGS_TO_STORE];
|
static can_status_msg stat_msgs[CAN_STATUS_MSGS_TO_STORE];
|
||||||
static Mutex can_mtx;
|
static Mutex can_mtx;
|
||||||
static uint8_t rx_buffer[256];
|
static uint8_t rx_buffer[256];
|
||||||
static uint8_t rx_buffer_last_id;
|
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
|
* 500KBaud, automatic wakeup, automatic recover
|
||||||
|
@ -68,6 +75,9 @@ void comm_can_init(void) {
|
||||||
stat_msgs[i].id = -1;
|
stat_msgs[i].id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rx_frame_read = 0;
|
||||||
|
rx_frame_write = 0;
|
||||||
|
|
||||||
chMtxInit(&can_mtx);
|
chMtxInit(&can_mtx);
|
||||||
|
|
||||||
palSetPadMode(GPIOB, 8,
|
palSetPadMode(GPIOB, 8,
|
||||||
|
@ -79,27 +89,22 @@ void comm_can_init(void) {
|
||||||
PAL_STM32_OTYPE_PUSHPULL |
|
PAL_STM32_OTYPE_PUSHPULL |
|
||||||
PAL_STM32_OSPEED_MID1);
|
PAL_STM32_OSPEED_MID1);
|
||||||
|
|
||||||
chMtxLock(&can_mtx);
|
|
||||||
canStart(&CANDx, &cancfg);
|
canStart(&CANDx, &cancfg);
|
||||||
chMtxUnlock();
|
|
||||||
|
|
||||||
chThdCreateStatic(cancom_thread_wa, sizeof(cancom_thread_wa), NORMALPRIO,
|
chThdCreateStatic(cancom_read_thread_wa, sizeof(cancom_read_thread_wa), NORMALPRIO + 1,
|
||||||
cancom_thread, NULL);
|
cancom_read_thread, NULL);
|
||||||
chThdCreateStatic(cancom_status_thread_wa, sizeof(cancom_status_thread_wa), NORMALPRIO,
|
chThdCreateStatic(cancom_status_thread_wa, sizeof(cancom_status_thread_wa), NORMALPRIO,
|
||||||
cancom_status_thread, NULL);
|
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;
|
(void)arg;
|
||||||
chRegSetThreadName("CAN");
|
chRegSetThreadName("CAN");
|
||||||
|
|
||||||
EventListener el;
|
EventListener el;
|
||||||
CANRxFrame rxmsg;
|
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);
|
chEvtRegister(&CANDx.rxfull_event, &el, 0);
|
||||||
|
|
||||||
|
@ -108,11 +113,42 @@ static msg_t cancom_thread(void *arg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
chMtxLock(&can_mtx);
|
|
||||||
msg_t result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE);
|
msg_t result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE);
|
||||||
chMtxUnlock();
|
|
||||||
|
|
||||||
while (result == RDY_OK) {
|
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) {
|
if (rxmsg.IDE == CAN_IDE_EXT) {
|
||||||
uint8_t id = rxmsg.EID & 0xFF;
|
uint8_t id = rxmsg.EID & 0xFF;
|
||||||
CAN_PACKET_ID cmd = rxmsg.EID >> 8;
|
CAN_PACKET_ID cmd = rxmsg.EID >> 8;
|
||||||
|
@ -214,13 +250,12 @@ static msg_t cancom_thread(void *arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chMtxLock(&can_mtx);
|
if (rx_frame_read == RX_FRAMES_SIZE) {
|
||||||
result = canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE);
|
rx_frame_read = 0;
|
||||||
chMtxUnlock();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chEvtUnregister(&CAND1.rxfull_event, &el);
|
|
||||||
return 0;
|
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) {
|
void comm_can_transmit(uint32_t id, uint8_t *data, uint8_t len) {
|
||||||
#if CAN_ENABLE
|
#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);
|
chMtxLock(&can_mtx);
|
||||||
|
canTransmit(&CANDx, CAN_ANY_MAILBOX, &txmsg, MS2ST(20));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
chMtxUnlock();
|
chMtxUnlock();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
(void)id;
|
(void)id;
|
||||||
(void)data;
|
(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 >> 8);
|
||||||
send_buffer[ind++] = (uint8_t)(crc & 0xFF);
|
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++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
commands.c
31
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -37,6 +37,8 @@
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
#include "servo_dec.h"
|
#include "servo_dec.h"
|
||||||
#include "comm_can.h"
|
#include "comm_can.h"
|
||||||
|
#include "flash_helper.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -107,6 +109,8 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
|
||||||
bool at_start;
|
bool at_start;
|
||||||
mc_configuration mcconf;
|
mc_configuration mcconf;
|
||||||
app_configuration appconf;
|
app_configuration appconf;
|
||||||
|
uint16_t flash_res;
|
||||||
|
uint32_t new_app_offset;
|
||||||
|
|
||||||
(void)len;
|
(void)len;
|
||||||
|
|
||||||
|
@ -123,6 +127,31 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
|
||||||
commands_send_packet(send_buffer, ind);
|
commands_send_packet(send_buffer, ind);
|
||||||
break;
|
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:
|
case COMM_GET_VALUES:
|
||||||
ind = 0;
|
ind = 0;
|
||||||
send_buffer[ind++] = COMM_GET_VALUES;
|
send_buffer[ind++] = COMM_GET_VALUES;
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
#ifndef CONF_GENERAL_H_
|
#ifndef CONF_GENERAL_H_
|
||||||
#define CONF_GENERAL_H_
|
#define CONF_GENERAL_H_
|
||||||
|
|
||||||
// Software version
|
// Firmware version
|
||||||
#define FW_VERSION_MAJOR 1
|
#define FW_VERSION_MAJOR 1
|
||||||
#define FW_VERSION_MINOR 0
|
#define FW_VERSION_MINOR 1
|
||||||
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,9 @@ typedef struct {
|
||||||
// Communication commands
|
// Communication commands
|
||||||
typedef enum {
|
typedef enum {
|
||||||
COMM_FW_VERSION = 0,
|
COMM_FW_VERSION = 0,
|
||||||
|
COMM_JUMP_TO_BOOTLOADER,
|
||||||
|
COMM_ERASE_NEW_APP,
|
||||||
|
COMM_WRITE_NEW_APP_DATA,
|
||||||
COMM_GET_VALUES,
|
COMM_GET_VALUES,
|
||||||
COMM_SET_DUTY,
|
COMM_SET_DUTY,
|
||||||
COMM_SET_CURRENT,
|
COMM_SET_CURRENT,
|
||||||
|
|
8
eeprom.h
8
eeprom.h
|
@ -36,18 +36,18 @@
|
||||||
#define VOLTAGE_RANGE (uint8_t)VoltageRange_3
|
#define VOLTAGE_RANGE (uint8_t)VoltageRange_3
|
||||||
|
|
||||||
/* EEPROM start address in Flash */
|
/* EEPROM start address in Flash */
|
||||||
#define EEPROM_START_ADDRESS ((uint32_t)0x08008000) /* EEPROM emulation start address:
|
#define EEPROM_START_ADDRESS ((uint32_t)0x08004000) /* EEPROM emulation start address:
|
||||||
from sector2 : after 16KByte of used
|
from sector1 : after 16KByte of used
|
||||||
Flash memory */
|
Flash memory */
|
||||||
|
|
||||||
/* Pages 0 and 1 base and end addresses */
|
/* Pages 0 and 1 base and end addresses */
|
||||||
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
|
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
|
||||||
#define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
|
#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_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x4000))
|
||||||
#define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))
|
#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 */
|
/* Used Flash pages for EEPROM emulation */
|
||||||
#define PAGE0 ((uint16_t)0x0000)
|
#define PAGE0 ((uint16_t)0x0000)
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_ */
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOC, 4)
|
#define LED_GREEN_ON() palSetPad(GPIOC, 4)
|
||||||
#define LED1_OFF() palClearPad(GPIOC, 4)
|
#define LED_GREEN_OFF() palClearPad(GPIOC, 4)
|
||||||
#define LED2_ON() palSetPad(GPIOA, 7)
|
#define LED_RED_ON() palSetPad(GPIOA, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOA, 7)
|
#define LED_RED_OFF() palClearPad(GPIOA, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOC, 4)
|
#define LED_GREEN_ON() palSetPad(GPIOC, 4)
|
||||||
#define LED1_OFF() palClearPad(GPIOC, 4)
|
#define LED_GREEN_OFF() palClearPad(GPIOC, 4)
|
||||||
#define LED2_ON() palSetPad(GPIOA, 7)
|
#define LED_RED_ON() palSetPad(GPIOA, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOA, 7)
|
#define LED_RED_OFF() palClearPad(GPIOA, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOC, 4)
|
#define LED_GREEN_ON() palSetPad(GPIOC, 4)
|
||||||
#define LED1_OFF() palClearPad(GPIOC, 4)
|
#define LED_GREEN_OFF() palClearPad(GPIOC, 4)
|
||||||
#define LED2_ON() palSetPad(GPIOA, 7)
|
#define LED_RED_ON() palSetPad(GPIOA, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOA, 7)
|
#define LED_RED_OFF() palClearPad(GPIOA, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOC, 4)
|
#define LED_GREEN_ON() palSetPad(GPIOC, 4)
|
||||||
#define LED1_OFF() palClearPad(GPIOC, 4)
|
#define LED_GREEN_OFF() palClearPad(GPIOC, 4)
|
||||||
#define LED2_ON() palSetPad(GPIOA, 7)
|
#define LED_RED_ON() palSetPad(GPIOA, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOA, 7)
|
#define LED_RED_OFF() palClearPad(GPIOA, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOB, 6)
|
#define LED_GREEN_ON() palSetPad(GPIOB, 6)
|
||||||
#define LED1_OFF() palClearPad(GPIOB, 6)
|
#define LED_GREEN_OFF() palClearPad(GPIOB, 6)
|
||||||
#define LED2_ON() palSetPad(GPIOB, 7)
|
#define LED_RED_ON() palSetPad(GPIOB, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOB, 7)
|
#define LED_RED_OFF() palClearPad(GPIOB, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
#define DCCAL_OFF() palClearPad(GPIOB, 12)
|
||||||
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
#define IS_DRV_FAULT() (!palReadPad(GPIOC, 12))
|
||||||
|
|
||||||
#define LED1_ON() palSetPad(GPIOC, 4)
|
#define LED_GREEN_ON() palSetPad(GPIOC, 4)
|
||||||
#define LED1_OFF() palClearPad(GPIOC, 4)
|
#define LED_GREEN_OFF() palClearPad(GPIOC, 4)
|
||||||
#define LED2_ON() palSetPad(GPIOA, 7)
|
#define LED_RED_ON() palSetPad(GPIOA, 7)
|
||||||
#define LED2_OFF() palClearPad(GPIOA, 7)
|
#define LED_RED_OFF() palClearPad(GPIOA, 7)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC Vector
|
* ADC Vector
|
||||||
|
|
|
@ -27,7 +27,7 @@ __process_stack_size__ = 0x0800;
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
flash : org = 0x08000000, len = 16k
|
flash : org = 0x08000000, len = 16k
|
||||||
flash2 : org = 0x08020000, len = 896k
|
flash2 : org = 0x0800C000, len = 480k
|
||||||
ram : org = 0x20000000, len = 128k
|
ram : org = 0x20000000, len = 128k
|
||||||
ccmram : org = 0x10000000, len = 64k
|
ccmram : org = 0x10000000, len = 64k
|
||||||
}
|
}
|
||||||
|
|
8
ledpwm.c
8
ledpwm.c
|
@ -91,14 +91,14 @@ void ledpwm_update_pwm(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt >= led_values[0]) {
|
if (cnt >= led_values[0]) {
|
||||||
LED1_OFF();
|
LED_GREEN_OFF();
|
||||||
} else {
|
} else {
|
||||||
LED1_ON();
|
LED_GREEN_ON();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt >= led_values[1]) {
|
if (cnt >= led_values[1]) {
|
||||||
LED2_OFF();
|
LED_RED_OFF();
|
||||||
} else {
|
} else {
|
||||||
LED2_ON();
|
LED_RED_ON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
main.c
2
main.c
|
@ -340,6 +340,6 @@ int main(void) {
|
||||||
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
|
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
chThdSleepMilliseconds(100);
|
chThdSleepMilliseconds(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
utils.c
42
utils.c
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "mcpwm.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// Private variables
|
// 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();
|
||||||
|
}
|
||||||
|
|
1
utils.h
1
utils.h
|
@ -34,6 +34,7 @@ void utils_deadband(float *value, float tres, float max);
|
||||||
float utils_angle_difference(float angle1, float angle2);
|
float utils_angle_difference(float angle1, float angle2);
|
||||||
void utils_sys_lock_cnt(void);
|
void utils_sys_lock_cnt(void);
|
||||||
void utils_sys_unlock_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.
|
// Return the sign of the argument. -1 if negative, 1 if zero or positive.
|
||||||
#define SIGN(x) ((x<0)?-1:1)
|
#define SIGN(x) ((x<0)?-1:1)
|
||||||
|
|
Loading…
Reference in New Issue