fix some bugs

This commit is contained in:
Edward Emelianov 2024-01-08 00:18:44 +03:00
parent 98b61c7e9a
commit 24a270a932
16 changed files with 265 additions and 96 deletions

Binary file not shown.

View File

@ -19,6 +19,8 @@
#include "adc.h" #include "adc.h"
#include "hardware.h" // ADCvals #include "hardware.h" // ADCvals
#include "usb.h"
/** /**
* @brief ADCx_array - arrays for ADC channels with median filtering: * @brief ADCx_array - arrays for ADC channels with median filtering:
* ADC1: * ADC1:
@ -73,6 +75,7 @@ void adc_setup(){
ADC1->SQR2 = (16<<0); ADC1->SQR2 = (16<<0);
ADC2->SMPR1 = ADC_SMPR1_SMP1; ADC2->SMPR1 = ADC_SMPR1_SMP1;
// configure DMA for ADC // configure DMA for ADC
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
ADC1->CFGR = ADC_CFGR_CONT | ADC_CFGR_DMAEN | ADC_CFGR_DMACFG; ADC1->CFGR = ADC_CFGR_CONT | ADC_CFGR_DMAEN | ADC_CFGR_DMACFG;
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
DMA1_Channel1->CMAR = (uint32_t)(ADC_array); DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
@ -104,18 +107,19 @@ uint16_t getADCval(int nch){
PIX_SORT(p[4], p[2]) ; PIX_SORT(p[4], p[2]) ;
#undef PIX_SORT #undef PIX_SORT
#undef PIX_SWAP #undef PIX_SWAP
DBG("nch="); printu(nch); USB_sendstr("; data="); printu(p[4]); newline();
return p[4]; return p[4];
} }
// get voltage @input nch (V) // get voltage @input nch (V)
float getADCvoltage(uint16_t ADCval){ float getADCvoltage(int nch){
float v = (float)ADCval * 3.3; float v = getADCval(nch) * 3.3f;
return v/4096.f; // 12bit ADC return v/4096.f; // 12bit ADC
} }
// return MCU temperature (degrees of celsius) // return MCU temperature (degrees of celsius)
float getMCUtemp(){ float getMCUtemp(){
float temperature = ADC_array[ADC_TSENS] - (float) *TEMP30_CAL_ADDR; float temperature = getADCval(ADC_TSENS) - (float) *TEMP30_CAL_ADDR;
temperature *= (110.f - 30.f); temperature *= (110.f - 30.f);
temperature /= (float)(*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR); temperature /= (float)(*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR);
temperature += 30.f; temperature += 30.f;

View File

@ -33,4 +33,4 @@
void adc_setup(); void adc_setup();
float getMCUtemp(); float getMCUtemp();
uint16_t getADCval(int nch); uint16_t getADCval(int nch);
float getADCvoltage(uint16_t ADCval); float getADCvoltage(int nch);

View File

@ -24,10 +24,16 @@
#include "strfunc.h" #include "strfunc.h"
#include "usb.h" #include "usb.h"
#ifdef EBUG
#undef EBUG
#endif
// PD1 - Tx, PD0 - Rx !!! // PD1 - Tx, PD0 - Rx !!!
#include <string.h> // memcpy #include <string.h> // memcpy
uint8_t cansniffer = 0; // 0 - receive only 0 and myID, 1 - receive all
// circular buffer for received messages // circular buffer for received messages
static CAN_message messages[CAN_INMESSAGE_SIZE]; static CAN_message messages[CAN_INMESSAGE_SIZE];
static uint8_t first_free_idx = 0; // index of first empty cell static uint8_t first_free_idx = 0; // index of first empty cell
@ -45,8 +51,9 @@ static CAN_message loc_flood_msg;
static CAN_message *flood_msg = NULL; // == loc_flood_msg - to flood static CAN_message *flood_msg = NULL; // == loc_flood_msg - to flood
CAN_status CAN_get_status(){ CAN_status CAN_get_status(){
int st = can_status; CAN_status st = can_status;
can_status = CAN_OK; //can_status = CAN_OK;
if(st == CAN_FIFO_OVERRUN) can_status = CAN_READY;
return st; return st;
} }
@ -95,7 +102,7 @@ CAN_message *CAN_messagebuf_pop(){
return msg; return msg;
} }
void CAN_reinit(uint16_t speed){ void CAN_reinit(uint32_t speed){
CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
RCC->APB1RSTR |= RCC_APB1RSTR_CANRST; RCC->APB1RSTR |= RCC_APB1RSTR_CANRST;
RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST; RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST;
@ -127,8 +134,8 @@ so if TBS1=4 and TBS2=3, sum=8, bit sampling freq is 36/8 = 4.5MHz
// GPIO configured in hw_setup // GPIO configured in hw_setup
void CAN_setup(uint32_t speed){ void CAN_setup(uint32_t speed){
if(speed == 0) speed = oldspeed; if(speed == 0) speed = oldspeed;
else if(speed < 50) speed = 50; else if(speed < CAN_MIN_SPEED) speed = CAN_MIN_SPEED;
else if(speed > 3000) speed = 3000; else if(speed > CAN_MAX_SPEED) speed = CAN_MAX_SPEED;
uint32_t tmout = 10000; uint32_t tmout = 10000;
/* Enable the peripheral clock CAN */ /* Enable the peripheral clock CAN */
RCC->APB1ENR |= RCC_APB1ENR_CANEN; RCC->APB1ENR |= RCC_APB1ENR_CANEN;
@ -141,7 +148,7 @@ void CAN_setup(uint32_t speed){
/* (6) Wait the init mode leaving */ /* (6) Wait the init mode leaving */
/* (7) Enter filter init mode, (16-bit + mask, bank 0 for FIFO 0) */ /* (7) Enter filter init mode, (16-bit + mask, bank 0 for FIFO 0) */
/* (8) Acivate filter 0 for two IDs */ /* (8) Acivate filter 0 for two IDs */
/* (9) Identifier list mode */ /* (9) Identifier mode for bank#0, mask mode for #1 */
/* (10) Set the Id list */ /* (10) Set the Id list */
/* (12) Leave filter init */ /* (12) Leave filter init */
/* (13) Set error interrupts enable (& bus off) */ /* (13) Set error interrupts enable (& bus off) */
@ -151,21 +158,28 @@ void CAN_setup(uint32_t speed){
if(tmout==0){ DBG("timeout!\n");} if(tmout==0){ DBG("timeout!\n");}
CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */ CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
CAN->BTR = 2 << 20 | 3 << 16 | (((uint32_t)4500000UL)/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
CAN->BTR = 2 << 20 | 3 << 16 | (4500000/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */ oldspeed = ((uint32_t)4500000UL)/(uint32_t)((CAN->BTR & CAN_BTR_BRP) + 1);
oldspeed = 4500000/((CAN->BTR & CAN_BTR_BRP) + 1);
CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */ CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */
tmout = 10000; tmout = 10000;
while(CAN->MSR & CAN_MSR_INAK) /* (6) */ while(CAN->MSR & CAN_MSR_INAK) /* (6) */
if(--tmout == 0) break; if(--tmout == 0) break;
if(tmout==0){ DBG("timeout!\n");} if(tmout==0){ DBG("timeout!\n");}
// accept ALL // accept only 0 & ID or ALL depending on `cansniffer` value
CAN->FMR = CAN_FMR_FINIT; /* (7) */ CAN->FMR = CAN_FMR_FINIT; /* (7) */
CAN->FA1R = CAN_FA1R_FACT0 | CAN_FA1R_FACT1; /* (8) */ CAN->FA1R = CAN_FA1R_FACT0; /* (8) */
// set to 1 all needed bits of CAN->FFA1R to switch given filters to FIFO1 CAN->FM1R = CAN_FM1R_FBM0; /* (9) */
CAN->sFilterRegister[0].FR1 = (1<<21)|(1<<5); // all odd IDs // CAN->FSCx = 0 -> dual 16-bit scale configuration
CAN->FFA1R = 2; // filter 1 for FIFO1, filter 0 - for FIFO0 // filter 0 for FIFO0
CAN->sFilterRegister[1].FR1 = (1<<21); // all even IDs CAN->sFilterRegister[0].FR1 = the_conf.CANID << 5; // (10) CANID and 0
if(cansniffer){ /* (11) */
CAN->FA1R |= CAN_FA1R_FACT1; // activate filter1
CAN->sFilterRegister[1].FR1 = 0; // all packets
// mask mode, all odd and even IDs
//CAN->sFilterRegister[1].FR1 = (1<<21)|(1<<5); // all odd IDs, mask mode
//CAN->sFilterRegister[1].FR2 = (1<<21)|(0<<5); // all even IDs, mask mode
CAN->FFA1R = 2; // filter 1 for FIFO1
}
CAN->FMR &= ~CAN_FMR_FINIT; /* (12) */ CAN->FMR &= ~CAN_FMR_FINIT; /* (12) */
CAN->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_BOFIE; /* (13) */ CAN->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_BOFIE; /* (13) */
@ -180,6 +194,15 @@ void CAN_setup(uint32_t speed){
can_status = CAN_READY; can_status = CAN_READY;
} }
/**
* @brief CAN_sniffer - reconfigure CAN in sniffer or normal mode
* @param issniffer - ==0 for normal mode
*/
void CAN_sniffer(uint8_t issniffer){
cansniffer = issniffer;
CAN_reinit(0);
}
void CAN_printerr(){ void CAN_printerr(){
if(!last_err_code) last_err_code = CAN->ESR; if(!last_err_code) last_err_code = CAN->ESR;
if(!last_err_code){ if(!last_err_code){
@ -228,14 +251,9 @@ void CAN_proc(){
} }
IWDG->KR = IWDG_REFRESH; IWDG->KR = IWDG_REFRESH;
if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
USB_sendstr("\nToo much errors, restarting CAN!\n"); USB_sendstr("error=canbuserr\n");
CAN_printerr(); CAN_printerr();
// request abort for all mailboxes CAN_reinit(0);
CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
// reset CAN bus
RCC->APB1RSTR |= RCC_APB1RSTR_CANRST;
RCC->APB1RSTR &= ~RCC_APB1RSTR_CANRST;
CAN_setup(0);
} }
static uint32_t lastFloodTime = 0; static uint32_t lastFloodTime = 0;
static uint32_t incrmessagectr = 0; static uint32_t incrmessagectr = 0;
@ -255,11 +273,17 @@ CAN_status CAN_send(CAN_message *message){
uint8_t *msg = message->data; uint8_t *msg = message->data;
uint8_t len = message->length; uint8_t len = message->length;
uint16_t target_id = message->ID; uint16_t target_id = message->ID;
uint8_t mailbox = 0; uint8_t mailbox = 0xff;
// check first free mailbox // check first free mailbox
if(CAN->TSR & (CAN_TSR_TME)){ uint32_t Tstart = Tms;
mailbox = (CAN->TSR & CAN_TSR_CODE) >> 24; while(Tms - Tstart < SEND_TIMEOUT_MS/10){
}else{ // no free mailboxes IWDG->KR = IWDG_REFRESH;
if(CAN->TSR & (CAN_TSR_TME)){
mailbox = (CAN->TSR & CAN_TSR_CODE) >> 24;
break;
}
}
if(mailbox == 0xff){// no free mailboxes
#ifdef EBUG #ifdef EBUG
USB_sendstr("No free mailboxes\n"); USB_sendstr("No free mailboxes\n");
#endif #endif
@ -336,9 +360,13 @@ TRUE_INLINE void parseCANcommand(CAN_message *msg){
msg->ID = the_conf.CANID; // set own ID for broadcast messages msg->ID = the_conf.CANID; // set own ID for broadcast messages
// check PING // check PING
if(msg->length != 0) run_can_cmd(msg); if(msg->length != 0) run_can_cmd(msg);
int N = 1000; uint32_t Tstart = Tms;
while(CAN_BUSY == CAN_send(msg)) while(Tms - Tstart < SEND_TIMEOUT_MS){
if(--N == 0) break; if(CAN_OK == CAN_send(msg)) return;
IWDG->KR = IWDG_REFRESH;
}
// TODO: buzzer error can't send
USB_sendstr("error=canbusy\n");
} }
static void can_process_fifo(uint8_t fifo_num){ static void can_process_fifo(uint8_t fifo_num){
@ -354,6 +382,7 @@ static void can_process_fifo(uint8_t fifo_num){
// CAN_RDTxR: (16-31) - timestamp, (8-15) - filter match index, (0-3) - data length // CAN_RDTxR: (16-31) - timestamp, (8-15) - filter match index, (0-3) - data length
/* TODO: check filter match index if more than one ID can receive */ /* TODO: check filter match index if more than one ID can receive */
CAN_message msg; CAN_message msg;
bzero(&msg, sizeof(msg));
uint8_t *dat = msg.data; uint8_t *dat = msg.data;
uint8_t len = box->RDTR & 0x0f; uint8_t len = box->RDTR & 0x0f;
msg.length = len; msg.length = len;
@ -389,7 +418,7 @@ static void can_process_fifo(uint8_t fifo_num){
} }
} }
if(msg.ID == the_conf.CANID || msg.ID == 0) parseCANcommand(&msg); if(msg.ID == the_conf.CANID || msg.ID == 0) parseCANcommand(&msg);
if(CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later if(cansniffer && CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later
*RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message *RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message
} }
//if(*RFxR & CAN_RF0R_FULL0) *RFxR &= ~CAN_RF0R_FULL0; //if(*RFxR & CAN_RF0R_FULL0) *RFxR &= ~CAN_RF0R_FULL0;

View File

@ -20,14 +20,21 @@
#include <stdint.h> #include <stdint.h>
// min/max speeds in bps
#define CAN_MAX_SPEED ((uint32_t)3000000UL)
#define CAN_MIN_SPEED ((uint32_t)9600UL)
// amount of filter banks in STM32F0 // amount of filter banks in STM32F0
#define STM32F0FBANKNO 28 #define STM32F0FBANKNO (28)
// flood period in milliseconds // flood period in milliseconds
#define FLOOD_PERIOD_MS 5 #define FLOOD_PERIOD_MS (5)
// wait to send not more tnah
#define SEND_TIMEOUT_MS (100)
// incoming message buffer size // incoming message buffer size
#define CAN_INMESSAGE_SIZE (8) #define CAN_INMESSAGE_SIZE (8)
extern uint32_t floodT; extern uint32_t floodT;
extern uint8_t cansniffer;
// CAN message // CAN message
typedef struct{ typedef struct{
@ -47,8 +54,9 @@ typedef enum{
CAN_status CAN_get_status(); CAN_status CAN_get_status();
void CAN_reinit(uint16_t speed); void CAN_reinit(uint32_t speed);
void CAN_setup(uint32_t speed); void CAN_setup(uint32_t speed);
void CAN_sniffer(uint8_t issniffer);
CAN_status CAN_send(CAN_message *message); CAN_status CAN_send(CAN_message *message);
void CAN_proc(); void CAN_proc();

View File

@ -49,7 +49,7 @@ static errcodes mcut(CAN_message *msg){
// get ADC raw values // get ADC raw values
static errcodes adcraw(CAN_message *msg){ static errcodes adcraw(CAN_message *msg){
FIXDL(msg); FIXDL(msg);
register uint8_t no = msg->data[2] & ~SETTER_FLAG; uint8_t no = msg->data[2] & ~SETTER_FLAG;
if(no >= NUMBER_OF_ADC_CHANNELS) return ERR_BADPAR; if(no >= NUMBER_OF_ADC_CHANNELS) return ERR_BADPAR;
*(uint32_t*)&msg->data[4] = getADCval(no); *(uint32_t*)&msg->data[4] = getADCval(no);
return ERR_OK; return ERR_OK;
@ -57,7 +57,7 @@ static errcodes adcraw(CAN_message *msg){
// get ADC voltage // get ADC voltage
static errcodes adcv(CAN_message *msg){ static errcodes adcv(CAN_message *msg){
FIXDL(msg); FIXDL(msg);
register uint8_t no = msg->data[2] & ~SETTER_FLAG; uint8_t no = msg->data[2] & ~SETTER_FLAG;
if(no >= ADC_TSENS) return ERR_BADPAR; if(no >= ADC_TSENS) return ERR_BADPAR;
float v = getADCvoltage(no) * the_conf.adcmul[no] * 100.f; float v = getADCvoltage(no) * the_conf.adcmul[no] * 100.f;
*(uint32_t*)&msg->data[4] = (uint32_t) v; // or float?? *(uint32_t*)&msg->data[4] = (uint32_t) v; // or float??
@ -67,7 +67,7 @@ static errcodes adcv(CAN_message *msg){
static errcodes canspeed(CAN_message *msg){ static errcodes canspeed(CAN_message *msg){
if(ISSETTER(msg->data)){ if(ISSETTER(msg->data)){
uint32_t spd = *(uint32_t*)&msg->data[4]; uint32_t spd = *(uint32_t*)&msg->data[4];
CAN_setup(spd); CAN_reinit(spd);
the_conf.CANspeed = CAN_speed(); the_conf.CANspeed = CAN_speed();
}else FIXDL(msg); }else FIXDL(msg);
*(uint32_t*)&msg->data[4] = CAN_speed(); *(uint32_t*)&msg->data[4] = CAN_speed();
@ -77,7 +77,7 @@ static errcodes canspeed(CAN_message *msg){
static errcodes canid(CAN_message *msg){ static errcodes canid(CAN_message *msg){
if(ISSETTER(msg->data)){ if(ISSETTER(msg->data)){
the_conf.CANID = *(uint32_t*)&msg->data[4]; the_conf.CANID = *(uint32_t*)&msg->data[4];
// CAN_setup(0); // setup with new ID CAN_reinit(0); // setup with new ID
}else FIXDL(msg); }else FIXDL(msg);
*(uint32_t*)&msg->data[4] = the_conf.CANID; *(uint32_t*)&msg->data[4] = the_conf.CANID;
return ERR_OK; return ERR_OK;
@ -121,7 +121,7 @@ static const commonfunction funclist[CMD_AMOUNT] = {
[CMD_MCUTEMP] = {mcut, 0, 0, 0}, [CMD_MCUTEMP] = {mcut, 0, 0, 0},
[CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..4 [CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..4
[CMD_ADCV] = {adcv, 0, 0, 3}, // need parno: 0..3 [CMD_ADCV] = {adcv, 0, 0, 3}, // need parno: 0..3
[CMD_CANSPEED] = {canspeed, 50, 3000, 0}, [CMD_CANSPEED] = {canspeed, CAN_MIN_SPEED, CAN_MAX_SPEED, 0},
[CMD_CANID] = {canid, 1, 0x7ff, 0}, [CMD_CANID] = {canid, 1, 0x7ff, 0},
[CMD_ADCMUL] = {adcmul, 0, 0, 3}, // at least parno [CMD_ADCMUL] = {adcmul, 0, 0, 3}, // at least parno
[CMD_SAVECONF] = {saveconf, 0, 0, 0}, [CMD_SAVECONF] = {saveconf, 0, 0, 0},
@ -148,33 +148,39 @@ void run_can_cmd(CAN_message *msg){
for(int i = 0; i < msg->length; ++i){ for(int i = 0; i < msg->length; ++i){
USB_sendstr(uhex2str(msg->data[i])); USB_putbyte(' '); USB_sendstr(uhex2str(msg->data[i])); USB_putbyte(' ');
} }
for(int i = msg->length-1; i < 8; ++i) msg->data[i] = 0; //for(int i = msg->length-1; i < 8; ++i) msg->data[i] = 0;
newline(); newline();
#endif #endif
if(datalen < 2){ if(datalen < 2){
FORMERR(data, ERR_WRONGLEN); FORMERR(msg, ERR_WRONGLEN);
return; return;
} }
uint16_t idx = *(uint16_t*)data; uint16_t idx = *(uint16_t*)data;
if(idx >= CMD_AMOUNT || funclist[idx].fn == NULL){ // bad command index if(idx >= CMD_AMOUNT || funclist[idx].fn == NULL){ // bad command index
FORMERR(data, ERR_BADCMD); FORMERR(msg, ERR_BADCMD); return;
return;
} }
// check minimal length (2 or 3) // check minimal length (2 or 3)
if(funclist[idx].datalen > datalen){ if(funclist[idx].datalen > datalen){
FORMERR(data, ERR_WRONGLEN); return; FORMERR(msg, ERR_WRONGLEN); return;
} }
if(datalen > 3 && (data[2] & SETTER_FLAG)){ if(datalen > 3 && (data[2] & SETTER_FLAG)){
// check setter's length // check setter's length
if(datalen != 8){ FORMERR(data, ERR_WRONGLEN); return; } if(datalen != 8){ FORMERR(msg, ERR_WRONGLEN); return; }
// check setter's values // check setter's values
if(funclist[idx].maxval != funclist[idx].minval){ if(funclist[idx].maxval != funclist[idx].minval){
int32_t newval = *(int32_t*)&data[4]; int32_t newval = *(int32_t*)&data[4];
if(newval < funclist[idx].minval || newval > funclist[idx].maxval){ if(newval < funclist[idx].minval || newval > funclist[idx].maxval){
FORMERR(data, ERR_BADVAL); return; FORMERR(msg, ERR_BADVAL); return;
} }
} }
} }
data[3] = funclist[idx].fn(msg); // set error field as result of function data[3] = funclist[idx].fn(msg); // set error field as result of function
data[2] &= ~SETTER_FLAG; // and clear setter flag data[2] &= ~SETTER_FLAG; // and clear setter flag
#ifdef EBUG
DBG("Return data: ");
for(int i = 0; i < msg->length; ++i){
USB_sendstr(uhex2str(msg->data[i])); USB_putbyte(' ');
}
newline();
#endif
} }

View File

@ -35,8 +35,8 @@ static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
.userconf_sz = sizeof(user_conf) \ .userconf_sz = sizeof(user_conf) \
,.CANspeed = 100000 \ ,.CANspeed = 100000 \
,.CANID = 0xaa \ ,.CANID = 0xaa \
,.adcmul[0] = 1.f \ ,.adcmul[0] = 10.930f \
,.adcmul[1] = 1.f \ ,.adcmul[1] = 2.028f \
,.adcmul[2] = 1.f \ ,.adcmul[2] = 1.f \
,.adcmul[3] = 1.f \ ,.adcmul[3] = 1.f \
} }
@ -145,12 +145,11 @@ static int write2flash(const void *start, const void *wrdata, uint32_t stor_size
// erase Nth page of flash storage (flash should be prepared!) // erase Nth page of flash storage (flash should be prepared!)
static int erase_pageN(int N){ static int erase_pageN(int N){
int ret = 0; int ret = 0;
#ifdef EBUG
USB_sendstr("Erase block #"); printu(N); newline();
#endif
FLASH->AR = (uint32_t)Flash_Data + N*FLASH_blocksize; FLASH->AR = (uint32_t)Flash_Data + N*FLASH_blocksize;
FLASH->CR |= FLASH_CR_STRT; FLASH->CR |= FLASH_CR_STRT;
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH; uint32_t xx = 100000;
while((FLASH->SR & FLASH_SR_BSY) && --xx) IWDG->KR = IWDG_REFRESH;
if(xx == 0) return 1;
FLASH->SR = FLASH_SR_EOP; FLASH->SR = FLASH_SR_EOP;
if(FLASH->SR & FLASH_SR_WRPERR){ /* Check Write protection error */ if(FLASH->SR & FLASH_SR_WRPERR){ /* Check Write protection error */
ret = 1; ret = 1;
@ -167,8 +166,9 @@ int erase_storage(int npage){
flsz = FLASH_SIZE * 1024; // size in bytes flsz = FLASH_SIZE * 1024; // size in bytes
flsz -= (uint32_t)Flash_Data - FLASH_BASE; flsz -= (uint32_t)Flash_Data - FLASH_BASE;
} }
DBG("total free blocks: "); printu(flsz / FLASH_blocksize);
end = flsz / FLASH_blocksize; end = flsz / FLASH_blocksize;
if(end == 0 || end >= FLASH_SIZE) return 1; if(end == 0) return 1;
if(npage > -1){ // erase only one page if(npage > -1){ // erase only one page
if((uint32_t)npage >= end) return 1; if((uint32_t)npage >= end) return 1;
start = npage; start = npage;
@ -184,12 +184,15 @@ int erase_storage(int npage){
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH; while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
FLASH->CR |= FLASH_CR_PER; FLASH->CR |= FLASH_CR_PER;
__disable_irq();
for(uint32_t i = start; i < end; ++i){ for(uint32_t i = start; i < end; ++i){
IWDG->KR = IWDG_REFRESH;
if(erase_pageN(i)){ if(erase_pageN(i)){
ret = 1; ret = 1;
break; break;
} }
} }
__enable_irq();
FLASH->CR &= ~FLASH_CR_PER; FLASH->CR &= ~FLASH_CR_PER;
return ret; return ret;
} }

View File

@ -33,8 +33,8 @@
*/ */
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 CANspeed; // default CAN speed
uint16_t CANID; // identifier uint16_t CANID; // identifier
uint32_t CANspeed; // default CAN speed
float adcmul[ADC_TSENS]; // ADC voltage multipliers float adcmul[ADC_TSENS]; // ADC voltage multipliers
} user_conf; } user_conf;

View File

@ -19,13 +19,41 @@
#include "adc.h" #include "adc.h"
#include "hardware.h" #include "hardware.h"
#include "usart.h" #include "usart.h"
#include "usbhw.h"
#ifndef EBUG
TRUE_INLINE void iwdg_setup(){
uint32_t tmout = 16000000;
/* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */
/* (2) Wait while it is not ready */
RCC->CSR |= RCC_CSR_LSION; /* (1) */
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
/* Configure IWDG */
/* (1) Activate IWDG (not needed if done in option bytes) */
/* (2) Enable write access to IWDG registers */
/* (3) Set prescaler by 64 (1.6ms for each tick) */
/* (4) Set reload value to have a rollover each 2s */
/* (5) Check if flags are reset */
/* (6) Refresh counter */
IWDG->KR = IWDG_START; /* (1) */
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
IWDG->PR = IWDG_PR_PR_1; /* (3) */
IWDG->RLR = 1250; /* (4) */
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */
}
#endif
static inline void gpio_setup(){ static inline void gpio_setup(){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN;
// PWM - AF1 @PA7; USB - alternate function 14 @ pins PA11/PA12; USART1 = AF7 @PA9/10; SWD - AF0 @PA13/14 // PWM - AF1 @PA7; USB - alternate function 14 @ pins PA11/PA12; USART1 = AF7 @PA9/10; SWD - AF0 @PA13/14
GPIOA->AFR[0] = AFRf(1, 7); GPIOA->AFR[0] = AFRf(1, 7);
GPIOA->AFR[1] = AFRf(7, 9) | AFRf(7, 10) | AFRf(14, 11) | AFRf(14, 12); GPIOA->AFR[1] = AFRf(7, 9) | AFRf(7, 10) | AFRf(14, 11) | AFRf(14, 12);
// USART1: PA10(Rx), PA9(Tx); USB - PA11, PA12; SWDIO - PA13, PA14; // PA4 - din (PU in), USART1: PA10(Rx, pullup), PA9(Tx); USB - PA11, PA12; SWDIO - PA13, PA14; PA8 & PA15 - PU in
GPIOA->PUPDR = (GPIOA->PUPDR & PUPD_CLR(4) & PUPD_CLR(8) & PUPD_CLR(10) & PUPD_CLR(15)) |
PUPD_PU(4) | PUPD_PU(8) | PUPD_PU(10) | PUPD_PU(15);
GPIOA->MODER = MODER_AI(0) | MODER_AI(1) | MODER_AI(2) | MODER_AI(3) | MODER_I(4) | MODER_O(5) | GPIOA->MODER = MODER_AI(0) | MODER_AI(1) | MODER_AI(2) | MODER_AI(3) | MODER_I(4) | MODER_O(5) |
MODER_O(6) | MODER_AF(7) | MODER_I(8) | MODER_AF(9) | MODER_AF(10) | MODER_AF(11) | MODER_O(6) | MODER_AF(7) | MODER_I(8) | MODER_AF(9) | MODER_AF(10) | MODER_AF(11) |
MODER_AF(12) | MODER_AF(13) | MODER_AF(14) | MODER_I(15); MODER_AF(12) | MODER_AF(13) | MODER_AF(14) | MODER_I(15);
@ -33,6 +61,8 @@ static inline void gpio_setup(){
// SPI for SSI: AF5 @PB3, PB4; I2C1: AF4 @PB6, PB7; CAN: AF9 @PB8, PB9; SPI2: AF5 @PB12..PB15 // SPI for SSI: AF5 @PB3, PB4; I2C1: AF4 @PB6, PB7; CAN: AF9 @PB8, PB9; SPI2: AF5 @PB12..PB15
GPIOB->AFR[0] = AFRf(5, 3) | AFRf(5, 4) | AFRf(4, 6) | AFRf(4, 7); GPIOB->AFR[0] = AFRf(5, 3) | AFRf(5, 4) | AFRf(4, 6) | AFRf(4, 7);
GPIOB->AFR[1] = AFRf(9, 8) | AFRf(9, 9) | AFRf(5, 12) | AFRf(5, 13) | AFRf(5, 14) | AFRf(5, 15); GPIOB->AFR[1] = AFRf(9, 8) | AFRf(9, 9) | AFRf(5, 12) | AFRf(5, 13) | AFRf(5, 14) | AFRf(5, 15);
// PB10,11 - PU in
GPIOB->PUPDR = PUPD_PU(10) | PUPD_PU(11);
GPIOB->MODER = MODER_O(0) | MODER_O(1) | MODER_O(2) | MODER_AF(3) | MODER_AF(4) | MODER_AF(6) | MODER_AF(7) | GPIOB->MODER = MODER_O(0) | MODER_O(1) | MODER_O(2) | MODER_AF(3) | MODER_AF(4) | MODER_AF(6) | MODER_AF(7) |
MODER_AF(8) | MODER_AF(9) | MODER_I(10) | MODER_I(11) | MODER_AF(12) | MODER_AF(13) | MODER_AF(8) | MODER_AF(9) | MODER_I(10) | MODER_I(11) | MODER_AF(12) | MODER_AF(13) |
MODER_AF(14) | MODER_AF(15); MODER_AF(14) | MODER_AF(15);
@ -44,5 +74,10 @@ static inline void gpio_setup(){
void hw_setup(){ void hw_setup(){
gpio_setup(); gpio_setup();
adc_setup(); adc_setup();
//usart_setup(); - power it on only for encoders on RS-422
USB_setup();
#ifndef EBUG
iwdg_setup();
#endif
} }

View File

@ -31,6 +31,21 @@ void sys_tick_handler(void){
++Tms; ++Tms;
} }
TRUE_INLINE void showCANmessages(){
CAN_message *can_mesg = NULL;
while((can_mesg = CAN_messagebuf_pop())){
IWDG->KR = IWDG_REFRESH;
printu(Tms);
USB_sendstr(" #");
printuhex(can_mesg->ID);
for(int ctr = 0; ctr < can_mesg->length; ++ctr){
USB_putbyte(' ');
printuhex(can_mesg->data[ctr]);
}
newline();
}
}
int main(void){ int main(void){
char inbuff[MAXSTRLEN+1]; char inbuff[MAXSTRLEN+1];
USBPU_OFF(); USBPU_OFF();
@ -42,26 +57,31 @@ int main(void){
} }
flashstorage_init(); flashstorage_init();
hw_setup(); hw_setup();
usart_setup();
USB_setup();
CAN_setup(the_conf.CANspeed); CAN_setup(the_conf.CANspeed);
USBPU_ON(); USBPU_ON();
while(1){ while(1){
IWDG->KR = IWDG_REFRESH;
CAN_proc(); CAN_proc();
if(CAN_get_status() == CAN_FIFO_OVERRUN){ CAN_status stat = CAN_get_status();
if(stat == CAN_FIFO_OVERRUN){
USB_sendstr("CAN bus fifo overrun occured!\n"); USB_sendstr("CAN bus fifo overrun occured!\n");
// TODO: buzzer short
}else if(stat == CAN_ERR){
// TODO: buzzer errors
CAN_reinit(0);
} }
if(bufovr){ if(cansniffer) showCANmessages();
/*if(bufovr){
bufovr = 0; bufovr = 0;
usart_send("bufovr\n"); USB_sendstr("error=uartoverflow\n");
} }*/
char *txt = NULL; char *txt = NULL;
if(usart_getline(&txt)){ if(usart_getline(&txt)){
const char *ans = run_text_cmd(txt); const char *ans = run_text_cmd(txt);
if(ans) usart_send(ans); if(ans) usart_send(ans);
} }
int l = USB_receivestr(inbuff, MAXSTRLEN); int l = USB_receivestr(inbuff, MAXSTRLEN);
if(l < 0) USB_sendstr("error=overflow\n"); if(l < 0) USB_sendstr("error=usboverflow\n");
else if(l){ else if(l){
const char *ans = run_text_cmd(inbuff); const char *ans = run_text_cmd(inbuff);
if(ans) USB_sendstr(ans); if(ans) USB_sendstr(ans);

View File

@ -35,7 +35,7 @@
#define NO_PARNO (0x1f) #define NO_PARNO (0x1f)
// make error for CAN answer // make error for CAN answer
#define FORMERR(data, err) do{data[3] = err;}while(0) #define FORMERR(m, err) do{m->data[3] = err; if(m->length < 4) m->length = 4;}while(0)
// error codes for answer message // error codes for answer message
typedef enum{ typedef enum{

View File

@ -19,6 +19,7 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include "can.h"
#include "commonfunctions.h" #include "commonfunctions.h"
#include "flash.h" #include "flash.h"
#include "proto.h" #include "proto.h"
@ -32,10 +33,12 @@
// text-only commans indexes (0 is prohibited) // text-only commans indexes (0 is prohibited)
typedef enum{ typedef enum{
TCMD_PROHIBITED TCMD_PROHIBITED, // prohibited
,TCMD_WDTEST TCMD_WDTEST, // test watchdog
,TCMD_DUMPCONF TCMD_DUMPCONF, // dump configuration
,TCMD_AMOUNT TCMD_CANSNIF, // CAN sniffer/normal
TCMD_CANSEND, // send CAN message
TCMD_AMOUNT
} text_cmd; } text_cmd;
@ -47,15 +50,17 @@ typedef struct{
// list of all text functions; should be sorted and can be grouped // list of all text functions; should be sorted and can be grouped
static const funcdescr funclist[] = { static const funcdescr funclist[] = {
{"adcmul", CMD_ADCMUL, "get/set ADC multipliers 0..4 (*1000)"}, {"adcmul", CMD_ADCMUL, "get/set ADC multipliers 0..3 (*1000)"},
{"adcraw", CMD_ADCRAW, "get raw ADC values of channel 0..4"}, {"adcraw", CMD_ADCRAW, "get raw ADC values of channel 0..4"},
{"adcv", CMD_ADCV, "get ADC voltage of channel 0..3 (*100V)"}, {"adcv", CMD_ADCV, "get ADC voltage of channel 0..3 (*100V)"},
{"canid", CMD_CANID, "get/set CAN ID"}, {"canid", CMD_CANID, "get/set CAN ID"},
{"cansnif", -TCMD_CANSNIF, "get/change sniffer state (0 - normal, 1 - sniffer)"},
{"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"}, {"canspeed", CMD_CANSPEED, "get/set CAN speed (bps)"},
{"dumpconf", -TCMD_DUMPCONF, "dump current configuration"}, {"dumpconf", -TCMD_DUMPCONF, "dump current configuration"},
{"eraseflash", CMD_ERASESTOR, "erase all flash storage"}, {"eraseflash", CMD_ERASESTOR, "erase all flash storage"},
{"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"}, {"mcutemp", CMD_MCUTEMP, "get MCU temperature (*10degrC)"},
{"reset", CMD_RESET, "reset MCU"}, {"reset", CMD_RESET, "reset MCU"},
{"s", -TCMD_CANSEND, "send CAN message: ID 0..8 data bytes"},
{"saveconf", CMD_SAVECONF, "save configuration"}, {"saveconf", CMD_SAVECONF, "save configuration"},
{"time", CMD_TIME, "get/set time (ms)"}, {"time", CMD_TIME, "get/set time (ms)"},
{"wdtest", -TCMD_WDTEST, "test watchdog"}, {"wdtest", -TCMD_WDTEST, "test watchdog"},
@ -72,9 +77,10 @@ static errcodes wdtest(const char _U_ *str){
static errcodes dumpconf(const char _U_ *str){ static errcodes dumpconf(const char _U_ *str){
#ifdef EBUG #ifdef EBUG
USB_sendstr("flashsize="); printu(FLASH_SIZE); USB_putbyte('*'); uint32_t sz = FLASH_SIZE*1024;
printu(FLASH_blocksize); USB_putbyte('='); printu(FLASH_SIZE*FLASH_blocksize); USB_sendstr("flashsize="); printu(sz); USB_putbyte('/');
newline(); printu(FLASH_blocksize); USB_putbyte('='); printu(sz/FLASH_blocksize);
USB_sendstr(" blocks\n");
#endif #endif
USB_sendstr("userconf_addr="); printuhex((uint32_t)Flash_Data); USB_sendstr("userconf_addr="); printuhex((uint32_t)Flash_Data);
USB_sendstr("\nuserconf_idx="); printi(currentconfidx); USB_sendstr("\nuserconf_idx="); printi(currentconfidx);
@ -91,19 +97,75 @@ static errcodes dumpconf(const char _U_ *str){
return ERR_OK; return ERR_OK;
} }
static errcodes cansnif(const char *str){
uint32_t U;
if(str){
if(*str == '=') str = omit_spaces(str + 1);
const char *nxt = getnum(str, &U);
if(nxt != str){ // setter
CAN_sniffer((uint8_t)U);
}
}
USB_sendstr("cansnif="); USB_putbyte('0' + cansniffer); newline();
return ERR_OK;
}
static errcodes cansend(const char *txt){
CAN_message canmsg;
bzero(&canmsg, sizeof(canmsg));
int ctr = -1;
canmsg.ID = 0xffff;
do{
txt = omit_spaces(txt);
uint32_t N;
const char *n = getnum(txt, &N);
if(txt == n) break;
txt = n;
if(ctr == -1){
if(N > 0x7ff){
return ERR_BADPAR;
}
canmsg.ID = (uint16_t)(N&0x7ff);
ctr = 0;
continue;
}
if(ctr > 7){
return ERR_WRONGLEN;
}
if(N > 0xff){
return ERR_BADVAL;
}
canmsg.data[ctr++] = (uint8_t) N;
}while(1);
if(canmsg.ID == 0xffff){
return ERR_BADPAR;
}
canmsg.length = (uint8_t) ctr;
uint32_t Tstart = Tms;
while(Tms - Tstart < SEND_TIMEOUT_MS){
if(CAN_OK == CAN_send(&canmsg)){
USB_sendstr("OK\n");
return ERR_OK;
}
}
return ERR_CANTRUN;
}
/************ END of all common functions list (for `textfunctions`) ************/ /************ END of all common functions list (for `textfunctions`) ************/
// in `textfn` arg `str` is rest of input string (spaces-omitted) after command // in `textfn` arg `str` is rest of input string (spaces-omitted) after command
typedef errcodes (*textfn)(const char *str); typedef errcodes (*textfn)(const char *str);
// array of text-only functions // array of text-only functions
static textfn textfunctions[TCMD_AMOUNT] = { static textfn textfunctions[TCMD_AMOUNT] = {
[TCMD_PROHIBITED] = NULL [TCMD_PROHIBITED] = NULL,
,[TCMD_WDTEST] = wdtest [TCMD_WDTEST] = wdtest,
,[TCMD_DUMPCONF] = dumpconf [TCMD_DUMPCONF] = dumpconf,
[TCMD_CANSNIF] = cansnif,
[TCMD_CANSEND] = cansend,
}; };
static char stbuf[256], *bptr = NULL; static char stbuf[256], *bptr = stbuf;
static int blen = 0; static int blen = 255;
static void initbuf(){bptr = stbuf; blen = 255; *bptr = 0;} static void initbuf(){bptr = stbuf; blen = 255; *bptr = 0;}
static void bufputchar(char c){ static void bufputchar(char c){
if(blen == 0) return; if(blen == 0) return;
@ -111,6 +173,7 @@ static void bufputchar(char c){
*bptr = 0; *bptr = 0;
} }
static void add2buf(const char *s){ static void add2buf(const char *s){
if(!s) return;
while(blen && *s){ while(blen && *s){
*bptr++ = *s++; *bptr++ = *s++;
--blen; --blen;
@ -121,7 +184,7 @@ static void add2buf(const char *s){
static void printhelp(){ static void printhelp(){
const funcdescr *c = funclist; const funcdescr *c = funclist;
USB_sendstr("https://github.com/eddyem/stm32samples/tree/master/F3:F303/CANbus4BTA build#" BUILD_NUMBER " @ " BUILD_DATE "\n"); USB_sendstr("https://github.com/eddyem/stm32samples/tree/master/F3:F303/CANbus4BTA build#" BUILD_NUMBER " @ " BUILD_DATE "\n");
USB_sendstr("commands format: parameter[number][=setter]"); USB_sendstr("commands format: parameter[number][=setter]\n");
USB_sendstr("parameter [CAN idx] - help\n"); USB_sendstr("parameter [CAN idx] - help\n");
USB_sendstr("--------------------------\n"); USB_sendstr("--------------------------\n");
while(c->help){ while(c->help){
@ -168,9 +231,10 @@ static void errtext(errcodes e){
* WARNING! Sending help works only for USB! * WARNING! Sending help works only for USB!
*/ */
char *run_text_cmd(const char *str){ char *run_text_cmd(const char *str){
if(!str || !*str) goto ret;
char cmd[MAXCMDLEN + 1]; char cmd[MAXCMDLEN + 1];
errcodes ecode = ERR_BADCMD; errcodes ecode = ERR_BADCMD;
if(!str || !*str) goto ret; initbuf();
int idx = CMD_AMOUNT; int idx = CMD_AMOUNT;
const funcdescr *c = funclist; const funcdescr *c = funclist;
int l = 0; int l = 0;
@ -185,13 +249,13 @@ char *run_text_cmd(const char *str){
idx = c->idx; idx = c->idx;
break; break;
} }
++c;
} }
if(idx == CMD_AMOUNT){ // didn't found if(idx == CMD_AMOUNT){ // didn't found
// send help over USB // send help over USB
printhelp(); printhelp();
goto ret; goto ret;
} }
initbuf();
str = omit_spaces(ptr); str = omit_spaces(ptr);
if(idx < 0){ // text-only function if(idx < 0){ // text-only function
ecode = textfunctions[-idx](str); ecode = textfunctions[-idx](str);
@ -216,6 +280,7 @@ char *run_text_cmd(const char *str){
} }
str = omit_spaces(str); str = omit_spaces(str);
if(*str == '='){ // setter if(*str == '='){ // setter
++str;
ptr = getint(str, ((int32_t*)&data[4])); ptr = getint(str, ((int32_t*)&data[4]));
if(str == ptr){ if(str == ptr){
ecode = ERR_BADVAL; ecode = ERR_BADVAL;
@ -234,7 +299,7 @@ ret:
if(msg.length != 8){ if(msg.length != 8){
return "OK\n"; // non setters/getters will just print "OK" if all OK return "OK\n"; // non setters/getters will just print "OK" if all OK
}else{ }else{
add2buf(funclist[idx].cmd); add2buf(cmd);
data[2] &= ~SETTER_FLAG; data[2] &= ~SETTER_FLAG;
if(data[2] != NO_PARNO) add2buf(u2str(data[2])); if(data[2] != NO_PARNO) add2buf(u2str(data[2]));
bufputchar('='); bufputchar('=');

View File

@ -25,11 +25,11 @@
static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data
// ring buffers for incoming and outgoing data // ring buffers for incoming and outgoing data
static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ];
volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; static volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0};
volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; // used in usblib.c
// transmission is succesfull // transmission is succesfull
volatile uint8_t bufisempty = 1; static volatile uint8_t bufisempty = 1;
volatile uint8_t bufovrfl = 0; volatile uint8_t bufovrfl = 0; // used in usblib.c
void send_next(){ void send_next(){
if(bufisempty) return; if(bufisempty) return;

View File

@ -37,8 +37,8 @@
#define DBG(str) #define DBG(str)
#endif #endif
extern volatile ringbuffer rbout, rbin; extern volatile ringbuffer /* rbout, */ rbin;
extern volatile uint8_t bufisempty, bufovrfl; extern volatile uint8_t /* bufisempty, */ bufovrfl;
void send_next(); void send_next();
int USB_sendall(); int USB_sendall();
@ -48,10 +48,8 @@ int USB_sendstr(const char *string);
int USB_receive(uint8_t *buf, int len); int USB_receive(uint8_t *buf, int len);
int USB_receivestr(char *buf, int len); int USB_receivestr(char *buf, int len);
#ifdef EBUG
#include "strfunc.h" #include "strfunc.h"
#define printu(x) do{USB_sendstr(u2str(x));}while(0) #define printu(x) do{USB_sendstr(u2str(x));}while(0)
#define printi(x) do{USB_sendstr(i2str(x));}while(0) #define printi(x) do{USB_sendstr(i2str(x));}while(0)
#define printuhex(x) do{USB_sendstr(uhex2str(x));}while(0) #define printuhex(x) do{USB_sendstr(uhex2str(x));}while(0)
#define printf(x) do{USB_sendstr(float2str(x, 2));}while(0) #define printf(x) do{USB_sendstr(float2str(x, 2));}while(0)
#endif

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "22" #define BUILD_NUMBER "56"
#define BUILD_DATE "2024-01-07" #define BUILD_DATE "2024-01-08"

View File

@ -47,7 +47,7 @@ LIB_DIR := $(INC_DIR)/ld
############################################################################### ###############################################################################
# C flags # C flags
CFLAGS += -O2 -D__thumb2__=1 -MD CFLAGS += -D__thumb2__=1 -MD
CFLAGS += -Wall -Wextra -Wshadow -Wdouble-promotion CFLAGS += -Wall -Wextra -Wshadow -Wdouble-promotion
CFLAGS += -fshort-enums -ffunction-sections -fdata-sections CFLAGS += -fshort-enums -ffunction-sections -fdata-sections
#CFLAGS += -fno-common -fno-stack-protector #CFLAGS += -fno-common -fno-stack-protector
@ -91,12 +91,12 @@ endif
BUILDDATE := $(shell date +%Y-%m-%d) BUILDDATE := $(shell date +%Y-%m-%d)
# release: add LTO # release: add LTO
release: CFLAGS += -flto release: CFLAGS += -O2 -flto
release: LDFLAGS += -flto release: LDFLAGS += -flto
release: $(TARGFILE) bin list size release: $(TARGFILE) bin list size
#debug: add debug flags #debug: add debug flags
debug: CFLAGS += -DEBUG -Werror -g3 -gdwarf-2 debug: CFLAGS += -O0 -DEBUG -Werror -g3 -gdwarf-2
debug: TARGET := DEBUG debug: TARGET := DEBUG
debug: $(TARGFILE) bin list size debug: $(TARGFILE) bin list size
@ -123,6 +123,7 @@ $(VERSION_FILE): *.[ch]
@[ -f $(VERSION_FILE) ] || echo -e "#define BUILD_NUMBER \"0\"\n#define BUILD_DATE \"none\"" > $(VERSION_FILE) @[ -f $(VERSION_FILE) ] || echo -e "#define BUILD_NUMBER \"0\"\n#define BUILD_DATE \"none\"" > $(VERSION_FILE)
@echo " Generate version: $(NEXTVER) for date $(BUILDDATE)" @echo " Generate version: $(NEXTVER) for date $(BUILDDATE)"
@sed -i "s/#define BUILD_NUMBER.*/#define BUILD_NUMBER \"$(NEXTVER)\"/" $(VERSION_FILE) @sed -i "s/#define BUILD_NUMBER.*/#define BUILD_NUMBER \"$(NEXTVER)\"/" $(VERSION_FILE)
@sed -i "s/#define BUILDNO.*/#define BUILDNO $(NEXTVER)/" $(VERSION_FILE)
@sed -i "s/#define BUILD_DATE.*/#define BUILD_DATE \"$(BUILDDATE)\"/" $(VERSION_FILE) @sed -i "s/#define BUILD_DATE.*/#define BUILD_DATE \"$(BUILDDATE)\"/" $(VERSION_FILE)
$(OBJDIR)/proto.o: proto.c $(VERSION_FILE) $(OBJDIR)/proto.o: proto.c $(VERSION_FILE)