3steppers next stage

This commit is contained in:
Edward Emelianov 2021-10-24 22:29:43 +03:00
parent 9ece1bd91e
commit 9b4bb6c02f
49 changed files with 466 additions and 107 deletions

View File

@ -308,7 +308,7 @@ static void formerr(CAN_message *msg, errcodes err){
* @brief parseCANcommand - parser * @brief parseCANcommand - parser
* @param msg - incoming message @ my CANID * @param msg - incoming message @ my CANID
* FORMAT: * FORMAT:
* 0 1 2 3 4 5 6 7 * 0 1 2 3 4 5 6 7
* [CMD][PAR][errcode][VALUE] * [CMD][PAR][errcode][VALUE]
* CMD - uint16_t, PAR - uint8_t, errcode - one of CAN_errcodes, VALUE - int32_t * CMD - uint16_t, PAR - uint8_t, errcode - one of CAN_errcodes, VALUE - int32_t
* `errcode` of incoming message doesn't matter * `errcode` of incoming message doesn't matter
@ -330,14 +330,14 @@ TRUE_INLINE void parseCANcommand(CAN_message *msg){
goto sendmessage; goto sendmessage;
} }
msg->data[3] = ERR_OK; msg->data[3] = ERR_OK;
uint8_t *par = (uint8_t *)(&msg->data[2]); uint8_t par = msg->data[2];
if(*par & 0x80){ if(par & 0x80){
formerr(msg, ERR_BADPAR); formerr(msg, ERR_BADPAR);
goto sendmessage; goto sendmessage;
} }
int32_t *val = (int32_t *)(&msg->data[4]); int32_t *val = (int32_t *)(&msg->data[4]);
if(msg->length == 8) *par |= 0x80; if(msg->length == 8) par |= 0x80;
else if(msg->length == 2) *par = CANMESG_NOPAR; // no parameter else if(msg->length == 2) par = CANMESG_NOPAR; // no parameter
else if(msg->length != 3){ // wrong length else if(msg->length != 3){ // wrong length
formerr(msg, ERR_WRONGLEN); formerr(msg, ERR_WRONGLEN);
goto sendmessage; goto sendmessage;

View File

@ -20,16 +20,20 @@
#include "buttons.h" #include "buttons.h"
#include "can.h" #include "can.h"
#include "commonproto.h" #include "commonproto.h"
#include "flash.h"
#include "hardware.h" #include "hardware.h"
#ifdef EBUG
#include "strfunct.h"
#endif
/******* All functions from cmdlist[i].function *******/ /******* All functions from cmdlist[i].function *******/
static errcodes pingparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes pingparser(uint8_t _U_ par, int32_t _U_ *val){
return ERR_OK; // just echo all input data over CAN (or return OK to USB) return ERR_OK; // just echo all input data over CAN (or return OK to USB)
} }
static errcodes relayparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes relayparser(uint8_t par, int32_t *val){
if(ISSETTER(*par)){ if(ISSETTER(par)){
if(*val) ON(RELAY); if(*val) ON(RELAY);
else OFF(RELAY); else OFF(RELAY);
} }
@ -37,8 +41,8 @@ static errcodes relayparser(uint8_t _U_ *par, int32_t _U_ *val){
return ERR_OK; return ERR_OK;
} }
static errcodes buzzerparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes buzzerparser(uint8_t par, int32_t *val){
if(ISSETTER(*par)){ if(ISSETTER(par)){
if(*val) ON(BUZZER); if(*val) ON(BUZZER);
else OFF(BUZZER); else OFF(BUZZER);
} }
@ -46,8 +50,8 @@ static errcodes buzzerparser(uint8_t _U_ *par, int32_t _U_ *val){
return ERR_OK; return ERR_OK;
} }
static errcodes adcparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes adcparser(uint8_t par, int32_t *val){
uint8_t n = PARBASE(*par); uint8_t n = PARBASE(par);
if(n > NUMBER_OF_ADC_CHANNELS) return ERR_BADPAR; if(n > NUMBER_OF_ADC_CHANNELS) return ERR_BADPAR;
*val = (int32_t) getADCval(n); *val = (int32_t) getADCval(n);
return ERR_OK; return ERR_OK;
@ -55,51 +59,57 @@ static errcodes adcparser(uint8_t _U_ *par, int32_t _U_ *val){
// NON-STANDARD COMMAND!!!!!!! // NON-STANDARD COMMAND!!!!!!!
// errcode == keystate, value = last time!!!! // errcode == keystate, value = last time!!!!
static errcodes buttonsparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes buttonsparser(uint8_t par, int32_t *val){
#if BTNSNO > 4 uint8_t n = PARBASE(par);
#error "change the code!!!" if(n > BTNSNO-1){
#endif par = CANMESG_NOPAR; // the only chance to understand error
uint8_t n = PARBASE(*par);
if(n >= BTNSNO){
*par = CANMESG_NOPAR; // the only chance to understand error
return ERR_BADPAR; return ERR_BADPAR;
} }
return (uint8_t) keystate(n, (uint32_t*)val); return (uint8_t) keystate(n, (uint32_t*)val);
} }
static errcodes eswparser(uint8_t _U_ *par, int32_t _U_ *val){ // if N > amount of esw, return all (by bytes)
uint8_t n = PARBASE(*par); static errcodes eswparser(uint8_t par, int32_t *val){
if(n > ESWNO-1) return ERR_BADPAR; #if ESWNO > 4
#error "change the code!!!"
#endif
uint8_t n = PARBASE(par);
if(n > ESWNO-1){ // all
uint8_t *arr = (uint8_t*)val;
for(int i = 0; i < ESWNO; ++i)
*arr++ = ESW_state(i);
return ERR_OK;
}
*val = (int32_t)ESW_state(n); *val = (int32_t)ESW_state(n);
return ERR_OK; return ERR_OK;
} }
static errcodes mcutparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes mcutparser(uint8_t _U_ par, int32_t *val){
*val = getMCUtemp(); *val = getMCUtemp();
return ERR_OK; return ERR_OK;
} }
static errcodes mcuvddparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes mcuvddparser(uint8_t _U_ par, int32_t *val){
*val = getVdd(); *val = getVdd();
return ERR_OK; return ERR_OK;
} }
static errcodes resetparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes resetparser(uint8_t _U_ par, int32_t _U_ *val){
NVIC_SystemReset(); NVIC_SystemReset();
return ERR_OK; return ERR_OK;
} }
static errcodes timeparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes timeparser(uint8_t _U_ par, int32_t *val){
*val = Tms; *val = Tms;
return ERR_OK; return ERR_OK;
} }
static errcodes pwmparser(uint8_t _U_ *par, int32_t _U_ *val){ static errcodes pwmparser(uint8_t par, int32_t *val){
if(PARBASE(*par) > PWMCHMAX && *par != CANMESG_NOPAR) return ERR_BADPAR; if(PARBASE(par) > PWMCHMAX && par != CANMESG_NOPAR) return ERR_BADPAR;
#if PWMCHMAX != 0 #if PWMCHMAX != 0
#error "change the code!!!" #error "change the code!!!"
#endif #endif
if(ISSETTER(*par)){ if(ISSETTER(par)){
if(*val < 0 || *val > PWMMAX) return ERR_BADVAL; if(*val < 0 || *val > PWMMAX) return ERR_BADVAL;
PWMset((uint32_t)*val); PWMset((uint32_t)*val);
} }
@ -107,12 +117,65 @@ static errcodes pwmparser(uint8_t _U_ *par, int32_t _U_ *val){
return ERR_OK; return ERR_OK;
} }
static errcodes extparser(uint8_t _U_ *par, int32_t _U_ *val){
TRUE_INLINE void setextpar(uint8_t val, uint8_t i){
switch(val){
case 0:
EXT_CLEAR(i);
break;
case 1:
EXT_SET(i);
break;
default:
EXT_TOGGLE(i);
}
}
// if `par` is absent, set/get all values in subsequent bytes
// 1 - external signal high, 0 - low
// commands: 0 - reset, 1 - set, !!!!other - toggle!!!!
static errcodes extparser(uint8_t par, int32_t *val){
#if EXTNO > 4
#error "change the code!!!"
#endif
uint8_t n = PARBASE(par);
SEND("par="); printu(par);
SEND(", n="); bufputchar('0'+n); newline();
if(n > EXTNO-1){ // all
SEND("ALL\n");
uint8_t *arr = (uint8_t*)val;
if(ISSETTER(par)){
for(int i = 0; i < EXTNO; ++i)
setextpar(arr[i], i);
}
for(int i = 0; i < EXTNO; ++i){
arr[i] = EXT_CHK(i);
}
return ERR_OK;
}
if(ISSETTER(par))
setextpar((uint8_t)*val, n);
*val = (int32_t) EXT_CHK(n);
return ERR_OK; return ERR_OK;
} }
static errcodes saveconfparser(uint8_t _U_ par, int32_t _U_ *val){
if(store_userconf()) return ERR_CANTRUN;
return ERR_OK;
}
#if 0
typedef struct __attribute__((packed, aligned(4))){
uint16_t microsteps; // microsteps amount per step
uint16_t accdecsteps; // amount of steps need for full acceleration/deceleration cycle
uint16_t motspd; // max motor speed (steps per second)
uint32_t maxsteps; // maximal amount of steps from ESW0 to EWS3
defflags_t defflags; // default flags
} user_conf;
#endif
/* /*
static CAN_errcodes parser(const uint8_t _U_ *par, const int32_t _U_ *val){ static CAN_errcodes parser(const uint8_t _U_ par, const int32_t _U_ *val){
return CANERR_OK; return CANERR_OK;
}*/ }*/
@ -130,4 +193,6 @@ const commands cmdlist[CMD_AMOUNT] = {
[CMD_TIMEFROMSTART] = {"time", timeparser, "get time from start"}, [CMD_TIMEFROMSTART] = {"time", timeparser, "get time from start"},
[CMD_PWM] = {"pwm", pwmparser, "pwm value"}, [CMD_PWM] = {"pwm", pwmparser, "pwm value"},
[CMD_EXT] = {"ext", extparser, "external outputs"}, [CMD_EXT] = {"ext", extparser, "external outputs"},
[CMD_SAVECONF] = {"saveconf", saveconfparser, "save current configuration"},
}; };

View File

@ -24,7 +24,9 @@
#include "can.h" #include "can.h"
#ifndef _U_
#define _U_ __attribute__((unused)) #define _U_ __attribute__((unused))
#endif
// message have no parameter // message have no parameter
#define CANMESG_NOPAR (127) #define CANMESG_NOPAR (127)
@ -47,7 +49,7 @@ typedef enum{
// if(par &0x80) it is setter, if not - getter // if(par &0x80) it is setter, if not - getter
// if par == 0x127 it means absense of parameter!!! // if par == 0x127 it means absense of parameter!!!
// @return CANERR_OK (0) if OK or error code // @return CANERR_OK (0) if OK or error code
typedef errcodes (*fpointer)(uint8_t *par, int32_t *val); typedef errcodes (*fpointer)(uint8_t par, int32_t *val);
typedef struct{ typedef struct{
const char *command; // text command (up to 65536 commands) const char *command; // text command (up to 65536 commands)
@ -68,7 +70,9 @@ enum{
,CMD_TIMEFROMSTART // get time from start ,CMD_TIMEFROMSTART // get time from start
,CMD_PWM // PWM value ,CMD_PWM // PWM value
,CMD_EXT // value on EXTx outputs ,CMD_EXT // value on EXTx outputs
,CMD_AMOUNT // amount of CANBUS commands, pure USB commands coming after it ,CMD_SAVECONF // save configuration
// should be the last:
,CMD_AMOUNT // amount of common commands
}; };
extern const commands cmdlist[CMD_AMOUNT]; extern const commands cmdlist[CMD_AMOUNT];

View File

@ -26,20 +26,23 @@
#include "flash.h" #include "flash.h"
#include "strfunct.h" #include "strfunct.h"
extern const uint32_t __varsstart, _BLOCKSIZE;
static const uint32_t blocksize = (uint32_t)&_BLOCKSIZE;
// max amount of Config records stored (will be recalculate in flashstorage_init() // max amount of Config records stored (will be recalculate in flashstorage_init()
static uint32_t maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf); static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
#define USERCONF_INITIALIZER { \ #define USERCONF_INITIALIZER { \
.userconf_sz = sizeof(user_conf) \ .userconf_sz = sizeof(user_conf) \
,.defflags.reverse = 0 \
,.CANspeed = 100 \ ,.CANspeed = 100 \
,.microsteps = 16 \ ,.CANID = 0xaa \
,.accdecsteps = 25 \ ,.microsteps = {32, 32, 32} \
,.motspd = 1000 \ ,.accdecsteps = {25, 25, 25} \
,.maxsteps = 50000 \ ,.maxspd = {1000, 1000, 1000} \
,.maxsteps = {50000, 50000, 50000} \
,.motflags = {{0},{0},{0}} \
} }
static int erase_flash(const void*, const void*); static int erase_flash(const void*, const void*);
static int write2flash(const void*, const void*, uint32_t); static int write2flash(const void*, const void*, uint32_t);
// don't write `static` here, or get error: // don't write `static` here, or get error:
@ -83,7 +86,7 @@ static int binarySearch(int r, const uint8_t *start, int stor_size){
*/ */
void flashstorage_init(){ void flashstorage_init(){
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){ if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes uint32_t flsz = FLASH_SIZE * blocksize; // size in bytes
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE; flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
maxCnum = flsz / sizeof(user_conf); maxCnum = flsz / sizeof(user_conf);
} }
@ -147,13 +150,13 @@ static int erase_flash(const void *start, const void *end){
uint32_t nblocks = 1, flsz = 0; uint32_t nblocks = 1, flsz = 0;
if(!end){ // erase all remaining if(!end){ // erase all remaining
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){ if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
flsz = FLASH_SIZE * 1024; // size in bytes flsz = FLASH_SIZE * blocksize; // size in bytes
flsz -= (uint32_t)start - FLASH_BASE; flsz -= (uint32_t)start - FLASH_BASE;
} }
}else{ // erase a part }else{ // erase a part
flsz = (uint32_t)end - (uint32_t)start; flsz = (uint32_t)end - (uint32_t)start;
} }
nblocks = flsz / FLASH_BLOCK_SIZE; nblocks = flsz / blocksize;
if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1; if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1;
for(uint32_t i = 0; i < nblocks; ++i){ for(uint32_t i = 0; i < nblocks; ++i){
IWDG->KR = IWDG_REFRESH; IWDG->KR = IWDG_REFRESH;
@ -177,7 +180,7 @@ static int erase_flash(const void *start, const void *end){
/* (5) Clear EOP flag by software by writing EOP at 1 */ /* (5) Clear EOP flag by software by writing EOP at 1 */
/* (6) Reset the PER Bit to disable the page erase */ /* (6) Reset the PER Bit to disable the page erase */
FLASH->CR |= FLASH_CR_PER; /* (1) */ FLASH->CR |= FLASH_CR_PER; /* (1) */
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_BLOCK_SIZE; /* (2) */ FLASH->AR = (uint32_t)Flash_Data + i*blocksize; /* (2) */
FLASH->CR |= FLASH_CR_STRT; /* (3) */ FLASH->CR |= FLASH_CR_STRT; /* (3) */
while(!(FLASH->SR & FLASH_SR_EOP)); while(!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR |= FLASH_SR_EOP; /* (5)*/ FLASH->SR |= FLASH_SR_EOP; /* (5)*/
@ -191,16 +194,32 @@ static int erase_flash(const void *start, const void *end){
return ret; return ret;
} }
void dump_userconf(){ void dump_userconf(_U_ char *txt){
SEND("userconf_addr="); printuhex((uint32_t)Flash_Data); #ifdef EBUG
SEND("\nuserconf_sz="); printu(the_conf.userconf_sz); SEND("flashsize="); printu(FLASH_SIZE); bufputchar('*');
SEND("\nCANspeed="); printu(the_conf.CANspeed); printu(blocksize); bufputchar('='); printu(FLASH_SIZE*blocksize);
SEND("\nmicrosteps="); printu(the_conf.microsteps);
SEND("\naccdecsteps="); printu(the_conf.accdecsteps);
SEND("\nmotspd="); printu(the_conf.motspd);
SEND("\nmaxsteps="); printu(the_conf.maxsteps);
//flags
SEND("\nreverse="); bufputchar('0' + the_conf.defflags.reverse);
newline(); newline();
sendbuf(); #endif
SEND("userconf_addr="); printuhex((uint32_t)Flash_Data);
SEND("\nuserconf_idx="); printi(currentconfidx);
SEND("\nuserconf_sz="); printu(the_conf.userconf_sz);
SEND("\ncanspeed="); printu(the_conf.CANspeed);
SEND("\ncanid="); printu(the_conf.CANID);
// motors' data
for(int i = 0; i < MOTORSNO; ++i){
char cur = '0' + i;
#define PROPNAME(nm) do{newline(); SEND(nm); bufputchar(cur); bufputchar('=');}while(0)
PROPNAME("reverse");
bufputchar('0' + the_conf.motflags[i].reverse);
PROPNAME("microsteps");
printu(the_conf.microsteps[i]);
PROPNAME("accdecsteps");
printu(the_conf.accdecsteps[i]);
PROPNAME("maxspeed");
printu(the_conf.maxspd[i]);
PROPNAME("maxsteps");
printu(the_conf.maxsteps[i]);
#undef PROPNAME
}
NL();
} }

View File

@ -26,34 +26,42 @@
#include "hardware.h" #include "hardware.h"
#define FLASH_BLOCK_SIZE (1024) #ifndef _U_
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC) #define _U_ __attribute__((unused))
#endif
// register with flash size (in blocks)
#ifndef FLASH_SIZE_REG
blocksizeASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
#endif
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG) #define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
// motor flags
typedef struct{ typedef struct{
uint8_t reverse : 1; uint8_t reverse : 1;
} defflags_t; } motflags_t;
/* /*
* struct to save user configurations * struct to save user configurations
*/ */
typedef struct __attribute__((packed, aligned(4))){ typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number" uint16_t userconf_sz; // "magick number"
uint32_t maxsteps; // maximal amount of steps from ESW0 to EWS3 uint16_t CANspeed; // default CAN speed
uint16_t CANspeed; // default CAN speed uint16_t CANID; // identifier
uint16_t CANID; // identifier uint16_t microsteps[MOTORSNO]; // microsteps amount per step
uint16_t microsteps; // microsteps amount per step uint16_t accdecsteps[MOTORSNO]; // amount of steps need for full acceleration/deceleration cycle
uint16_t accdecsteps; // amount of steps need for full acceleration/deceleration cycle uint16_t maxspd[MOTORSNO]; // max motor speed (steps per second)
uint16_t motspd; // max motor speed (steps per second) uint32_t maxsteps[MOTORSNO]; // maximal amount of steps from ESW0 to EWS3
defflags_t defflags; // default flags motflags_t motflags[MOTORSNO]; // motor's flags
} user_conf; } user_conf;
extern user_conf the_conf; // global user config (read from FLASH to RAM) extern user_conf the_conf; // global user config (read from FLASH to RAM)
// data from ld-file: start address of storage // data from ld-file: start address of storage
extern const uint32_t __varsstart;
void flashstorage_init(); void flashstorage_init();
int store_userconf(); int store_userconf();
void dump_userconf(); void dump_userconf(_U_ char *txt);
#endif // __FLASH_H__ #endif // __FLASH_H__

View File

@ -18,6 +18,7 @@
#include "hardware.h" #include "hardware.h"
#include "can.h" #include "can.h"
#include "steppers.h"
// Buttons: PA10, PA13, PA14, PA15, pullup (0 active) // Buttons: PA10, PA13, PA14, PA15, pullup (0 active)
volatile GPIO_TypeDef *BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOA, GPIOA}; volatile GPIO_TypeDef *BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOA, GPIOA};
@ -75,21 +76,50 @@ void iwdg_setup(){
IWDG->KR = IWDG_REFRESH; /* (6) */ IWDG->KR = IWDG_REFRESH; /* (6) */
} }
void timers_setup(){ // motor's PWM
#if 0 static void setup_mpwm(TIM_TypeDef *TIM){
// TIM1 channels 1..3 - PWM output TIM->PSC = 999; // 48kHz
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable clocking TIM->ARR = 1000; // starting ARR value
TIM1->PSC = 9; // F=48/10 = 4.8MHz
TIM1->ARR = 255; // PWM frequency = 4800/256 = 18.75kHz
// PWM mode 1 (OCxM = 110), preload enable // PWM mode 1 (OCxM = 110), preload enable
TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE | TIM->CCMR1 = TIM_CCMR1_OC1M_2; // Force inactive
TIM->CCER = TIM_CCER_CC1E; // turn it on, active high
TIM->CCR1 = 1; // 20.8us for pulse duration, according to datasheet 1.9us is enough
TIM->BDTR |= TIM_BDTR_MOE; // enable main output
TIM->CR1 |= TIM_CR1_CEN; // enable timer
TIM->EGR |= TIM_EGR_UG; // force update generation
TIM->DIER = TIM_DIER_CC1IE; // allow CC interrupt (we should count steps)
}
/*
static void setup_enc(TIM_TypeDef *TIM, uint16_t arrval){
TIM->PSC = 9; // F=48/10 = 4.8MHz
TIM->ARR = arrval; // PWM frequency = 4800/256 = 18.75kHz
// PWM mode 1 (OCxM = 110), preload enable
TIM->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE |
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE; TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
TIM1->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE; TIM->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
TIM1->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // active high (CC1P=0), enable outputs TIM->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // active high (CC1P=0), enable outputs
TIM1->BDTR |= TIM_BDTR_MOE; // enable main output TIM->BDTR |= TIM_BDTR_MOE; // enable main output
TIM1->CR1 |= TIM_CR1_CEN; // enable timer TIM->CR1 |= TIM_CR1_CEN; // enable timer
TIM1->EGR |= TIM_EGR_UG; // force update generation TIM->EGR |= TIM_EGR_UG; // force update generation
#endif }*/
// timers 14,15,16,17 - PWM@ch1, 1,2,3 - encoders @ ch1/2
void timers_setup(){
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM14EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM15EN | RCC_APB2ENR_TIM16EN | RCC_APB2ENR_TIM17EN; // enable clocking
setup_mpwm(TIM14);
setup_mpwm(TIM15);
setup_mpwm(TIM16);
// setup PWM @ TIM17
TIM17->PSC = 5; // 8MHz for 31kHz PWM
TIM17->ARR = 254; // ARR for 8-bit PWM
TIM17->BDTR |= TIM_BDTR_MOE; // enable main output
TIM17->CCER = TIM_CCER_CC1E; // enable PWM output
TIM17->CR1 |= TIM_CR1_CEN; // enable timer
;
NVIC_EnableIRQ(TIM14_IRQn);
NVIC_EnableIRQ(TIM15_IRQn);
NVIC_EnableIRQ(TIM16_IRQn);
} }
// pause in milliseconds for some purposes // pause in milliseconds for some purposes
@ -98,6 +128,10 @@ void pause_ms(uint32_t pause){
while(Tms < Tnxt) nop(); while(Tms < Tnxt) nop();
} }
#ifndef STM32F072xB
#warning "Only F072 can jump to bootloader"
#endif
void Jump2Boot(){ // for STM32F072 void Jump2Boot(){ // for STM32F072
void (*SysMemBootJump)(void); void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFFC800; volatile uint32_t addr = 0x1FFFC800;
@ -125,3 +159,18 @@ void Jump2Boot(){ // for STM32F072
SysMemBootJump(); SysMemBootJump();
} }
// count steps @tim 14/15/16
static void stp_isr(TIM_TypeDef *TIM, int i){
++steps[i]; // count steps
TIM->SR = 0;
}
void tim14_isr(){
stp_isr(TIM14, 0);
}
void tim15_isr(){
stp_isr(TIM15, 1);
}
void tim16_isr(){
stp_isr(TIM16, 2);
}

Binary file not shown.

View File

@ -0,0 +1,23 @@
/*
* This file is part of the 3steppers project.
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* 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/>.
*/
#include "hardware.h"
#include "steppers.h"
int32_t steps[MOTORSNO] = {0,0,0};

View File

@ -0,0 +1,27 @@
/*
* This file is part of the 3steppers project.
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* 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/>.
*/
#pragma once
#ifndef STEPPERS_H__
#define STEPPERS_H__
#include <stm32f0.h>
extern int32_t steps[];
#endif // STEPPERS_H__

View File

@ -145,11 +145,9 @@ static void sendCANcommand(char *txt){
static void CANini(char *txt){ static void CANini(char *txt){
txt = omit_spaces(txt); txt = omit_spaces(txt);
int32_t N; int32_t N;
if(!txt) goto eofunc;
char *n = getnum(txt, &N); char *n = getnum(txt, &N);
if(txt == n){ if(txt == n) goto eofunc;
SEND("No speed given");
return;
}
if(N < 50){ if(N < 50){
SEND("Lowest speed is 50kbps"); SEND("Lowest speed is 50kbps");
return; return;
@ -157,9 +155,10 @@ static void CANini(char *txt){
SEND("Highest speed is 3000kbps"); SEND("Highest speed is 3000kbps");
return; return;
} }
the_conf.CANspeed = (uint16_t)N;
CAN_reinit((uint16_t)N); CAN_reinit((uint16_t)N);
SEND("Reinit CAN bus with speed "); eofunc:
printu(N); SEND("kbps"); SEND("canspeed="); printu(the_conf.CANspeed); NL();
} }
static void addIGN(char *txt){ static void addIGN(char *txt){
@ -348,7 +347,22 @@ static void add_filter(char *str){
printu(nfilt); SEND(" parameters"); printu(nfilt); SEND(" parameters");
} }
void getcanid(_U_ char *txt){ void canid(char *txt){
if(txt && *txt){
int good = FALSE;
char *eq = getchr(txt, '=');
if(eq){
eq = omit_spaces(eq+1);
if(eq){
int32_t N;
if(eq != getnum(eq, &N) && N > -1 && N < 0xfff){
the_conf.CANID = (uint16_t)N;
good = TRUE;
}
}
}
if(!good) SEND("CANID setter format: `canid=ID`, ID is 11bit\n");
}
SEND("canid="); printuhex(the_conf.CANID); SEND("canid="); printuhex(the_conf.CANID);
} }
@ -384,12 +398,13 @@ const speccommands scmdlist[] = {
{"dfu", bootldr, "activate DFU mode"}, {"dfu", bootldr, "activate DFU mode"},
{"filter", add_filter, "add/modify filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]"}, {"filter", add_filter, "add/modify filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]"},
{"canspeed", CANini, "CAN bus speed"}, {"canspeed", CANini, "CAN bus speed"},
{"canid", getcanid, "read CAN ID"}, {"canid", canid, "get/set CAN ID"},
{"listfilters", list_filters, "list all active filters"}, {"listfilters", list_filters, "list all active filters"},
{"ignbuf", print_ign_buf, "print ignore buffer"}, {"ignbuf", print_ign_buf, "print ignore buffer"},
{"pause", inpause, "pause IN packets displaying"}, {"pause", inpause, "pause IN packets displaying"},
{"resume", inresume, "resume IN packets displaying"}, {"resume", inresume, "resume IN packets displaying"},
{"send", sendCANcommand, "send data over CAN: send ID byte0 .. byteN"}, {"send", sendCANcommand, "send data over CAN: send ID byte0 .. byteN"},
{"dumpconf", dump_userconf, "dump current configuration"},
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
@ -470,10 +485,12 @@ void cmd_parser(char *txt){
} }
} }
// here we got command & ppar/pval -> call CMD // here we got command & ppar/pval -> call CMD
errcodes retcode = cmdlist[idx].function(&par, &val); errcodes retcode = cmdlist[idx].function(par, &val);
SEND(cmd); SEND(cmd);
if(par != CANMESG_NOPAR) printu(par & 0x7f); par &= 0x7f;
if(par != CANMESG_NOPAR) printu(par);
bufputchar('='); printi(val); bufputchar('='); printi(val);
SEND(" ("); printuhex((uint32_t)val); bufputchar(')');
if(ERR_OK != retcode){ if(ERR_OK != retcode){
SEND("\nERRCODE="); SEND("\nERRCODE=");
printu(retcode); printu(retcode);

View File

@ -40,8 +40,12 @@
#include "proto.h" // printout #include "proto.h" // printout
#include <string.h> // memcpy #include <string.h> // memcpy
extern const uint32_t __varsstart, _BLOCKSIZE;
// ld-script shoul include _BLOCKSIZE = 1024; (or 2048)
static const uint32_t blocksize = (uint32_t)&_BLOCKSIZE;
// max amount of Config records stored (will be recalculate in flashstorage_init() // max amount of Config records stored (will be recalculate in flashstorage_init()
static uint32_t maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf); static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
#define USERCONF_INITIALIZER { \ #define USERCONF_INITIALIZER { \
.userconf_sz = sizeof(user_conf) \ .userconf_sz = sizeof(user_conf) \
@ -92,7 +96,7 @@ static int binarySearch(int r, const uint8_t *start, int stor_size){
*/ */
void flashstorage_init(){ void flashstorage_init(){
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){ if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes uint32_t flsz = FLASH_SIZE * blocksize; // size in bytes
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE; flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
maxCnum = flsz / sizeof(user_conf); maxCnum = flsz / sizeof(user_conf);
//SEND("flsz="); printu(flsz); //SEND("flsz="); printu(flsz);
@ -161,13 +165,13 @@ static int erase_flash(const void *start, const void *end){
uint32_t nblocks = 1, flsz = 0; uint32_t nblocks = 1, flsz = 0;
if(!end){ // erase all remaining if(!end){ // erase all remaining
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){ if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
flsz = FLASH_SIZE * 1024; // size in bytes flsz = FLASH_SIZE * blocksize; // size in bytes
flsz -= (uint32_t)start - FLASH_BASE; flsz -= (uint32_t)start - FLASH_BASE;
} }
}else{ // erase a part }else{ // erase a part
flsz = (uint32_t)end - (uint32_t)start; flsz = (uint32_t)end - (uint32_t)start;
} }
nblocks = flsz / FLASH_BLOCK_SIZE; nblocks = flsz / blocksize;
if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1; if(nblocks == 0 || nblocks >= FLASH_SIZE) return 1;
for(uint32_t i = 0; i < nblocks; ++i){ for(uint32_t i = 0; i < nblocks; ++i){
#ifdef EBUG #ifdef EBUG
@ -194,7 +198,7 @@ static int erase_flash(const void *start, const void *end){
/* (5) Clear EOP flag by software by writing EOP at 1 */ /* (5) Clear EOP flag by software by writing EOP at 1 */
/* (6) Reset the PER Bit to disable the page erase */ /* (6) Reset the PER Bit to disable the page erase */
FLASH->CR |= FLASH_CR_PER; /* (1) */ FLASH->CR |= FLASH_CR_PER; /* (1) */
FLASH->AR = (uint32_t)Flash_Data + i*FLASH_BLOCK_SIZE; /* (2) */ FLASH->AR = (uint32_t)Flash_Data + i*blocksize; /* (2) */
FLASH->CR |= FLASH_CR_STRT; /* (3) */ FLASH->CR |= FLASH_CR_STRT; /* (3) */
while(!(FLASH->SR & FLASH_SR_EOP)); while(!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR |= FLASH_SR_EOP; /* (5)*/ FLASH->SR |= FLASH_SR_EOP; /* (5)*/
@ -210,6 +214,11 @@ static int erase_flash(const void *start, const void *end){
} }
void dump_userconf(){ void dump_userconf(){
#ifdef EBUG
SEND("flashsize="); printu(FLASH_SIZE); bufputchar('*');
printu(blocksize); bufputchar('='); printu(FLASH_SIZE*blocksize);
newline();
#endif
SEND("userconf_addr="); printuhex((uint32_t)Flash_Data); SEND("userconf_addr="); printuhex((uint32_t)Flash_Data);
SEND("\nuserconf_sz="); printu(the_conf.userconf_sz); SEND("\nuserconf_sz="); printu(the_conf.userconf_sz);
SEND("\nflags="); printuhex(the_conf.defflags); SEND("\nflags="); printuhex(the_conf.defflags);

View File

@ -26,22 +26,26 @@
#include "hardware.h" #include "hardware.h"
#define FLASH_BLOCK_SIZE (1024) #ifndef FLASH_SIZE_REG
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC) blocksizeASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
#endif
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG) #define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
typedef struct{
uint8_t flag1 : 1;
uint8_t flag2 : 1; //...
} defflags_t;
/* /*
* struct to save user configurations * struct to save user configurations
*/ */
typedef struct __attribute__((packed, aligned(4))){ typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number" uint16_t userconf_sz; // "magick number"
uint8_t defflags; // default flags
uint16_t CANspeed; // default CAN speed uint16_t CANspeed; // default CAN speed
defflags_t defflags; // default flags
} user_conf; } user_conf;
extern user_conf the_conf; // global user config (read from FLASH to RAM) extern user_conf the_conf; // global user config (read from FLASH to RAM)
// data from ld-file: start address of storage
extern const uint32_t __varsstart;
void flashstorage_init(); void flashstorage_init();
int store_userconf(); int store_userconf();

View File

@ -11,3 +11,26 @@ void printuhex(uint32_t val){
} }
} }
} }
// print 32bit unsigned int
void printu(uint32_t val){
char buf[11], *bufptr = &buf[10];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
register uint32_t o = val;
val /= 10;
*(--bufptr) = (o - 10*val) + '0';
}
}
addtobuf(bufptr);
}
void printi(int32_t val){
if(val < 0){
val = -val;
bufputchar('-');
}
printu((uint32_t)val);
}

View File

@ -0,0 +1,10 @@
#define STM32F0_FlashAddr 0x1FFFF7CC // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F0
#define STM32F1_FlashAddr 0x1FFFF7E0 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F1
#define STM32F2_FlashAddr 0x1FFF7A22 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F2
#define STM32F3_FlashAddr 0x1FFFF7CC // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F3
#define STM32F4_FlashAddr 0x1FFF7A22 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F4
#define STM32F7_FlashAddr 0x1FF0F442 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÆÌÜÛ-ÐÁÍÑÔÉ STM32F7
#define STM32L0_FlashAddr 0x1FF8007C // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32L0
#define STM32L1_FlashAddr 0x1FF8004C // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32L1
#define STM32L4_FlashAddr 0x1FFF75E0 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÅÍËÏÓÔÉ ÆÌÜÛ-ÐÁÍÑÔÉ STM32L4
#define STM32H7_FlashAddr 0x1FF0F442 // âÁÚÏ×ÙÊ ÁÄÒÅÓ ÆÌÜÛ-ÐÁÍÑÔÉ STM32H7

View File

@ -257,9 +257,10 @@ TRUE_INLINE void StartHSI48(){
/****************** FLASH Keys **********************************************/ /****************** FLASH Keys **********************************************/
#define RDP_Key ((uint16_t)0x00A5) #define RDP_Key ((uint16_t)0x00A5)
#define FLASH_KEY1 ((uint32_t)0x45670123) #define FLASH_KEY1 ((uint32_t)0x45670123)
#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) #define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7CC)
/************************* ADC *************************/ /************************* ADC *************************/
/* inner termometer calibration values /* inner termometer calibration values

View File

@ -190,6 +190,9 @@ IDR - input, ODR - output (or pullups management),
#define IWDG_WRITE_ACCESS (uint32_t)(0x00005555) #define IWDG_WRITE_ACCESS (uint32_t)(0x00005555)
#define IWDG_START (uint32_t)(0x0000CCCC) #define IWDG_START (uint32_t)(0x0000CCCC)
// flash size
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7E0)
#if 0 #if 0
/************************* ADC *************************/ /************************* ADC *************************/

View File

@ -73,7 +73,7 @@ SECTIONS {
.myvars : .myvars :
{ {
. = ALIGN(1024); . = ALIGN(_BLOCKSIZE);
__varsstart = ABSOLUTE(.); __varsstart = ABSOLUTE(.);
KEEP(*(.myvars)); KEEP(*(.myvars));
} > rom } > rom

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -0,0 +1,14 @@
/* Linker script for STM32F042x6, 32K flash, 6K RAM. */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
}
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */
INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
} }
_BLOCKSIZE = 2048;
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -73,8 +73,9 @@ SECTIONS {
.myvars : .myvars :
{ {
. = ALIGN(1024); . = ALIGN(_BLOCKSIZE);
KEEP(*(.myvars)) __varsstart = ABSOLUTE(.);
KEEP(*(.myvars));
} > rom } > rom
_ldata = LOADADDR(.data); _ldata = LOADADDR(.data);

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -0,0 +1,14 @@
/* Linker script for STM32F042x6, 32K flash, 6K RAM. */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
}
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */
INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -7,6 +7,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -0,0 +1,14 @@
/* Linker script for STM32F072xB, 128K flash, 16K RAM. */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
}
_BLOCKSIZE = 2048;
/* Include the common ld script. */
INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

View File

@ -26,6 +26,8 @@ MEMORY
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K
} }
PROVIDE(_BLOCKSIZE = 1024);
/* Include the common ld script. */ /* Include the common ld script. */
INCLUDE stm32f01234.ld INCLUDE stm32f01234.ld

BIN
stm32reg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB