Ver. 0.1.0. Storing data into flash.

This commit is contained in:
eddyem 2019-09-20 12:46:08 +03:00
parent 7be1737383
commit ffef1590fc
11 changed files with 170 additions and 117 deletions

View File

@ -9,7 +9,7 @@ MCU ?= F103x8
DENSITY ?= MD DENSITY ?= MD
# change this linking script depending on particular MCU model, # change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32F103xB.ld LDSCRIPT ?= stm32F103xB.ld
DEFS = -DVERSION=\"0.0.2\" DEFS = -DVERSION=\"0.1.0\"
# debug # debug
#DEFS += -DEBUG #DEFS += -DEBUG
# proxy GPS output over USART1 # proxy GPS output over USART1

Binary file not shown.

View File

@ -45,8 +45,8 @@
#include <string.h> // memcpy #include <string.h> // memcpy
// max amount of records stored: Config & Logs // max amount of records stored: Config & Logs
static int maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf); int maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
static int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf); int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
// common structure for all datatypes stored // common structure for all datatypes stored
/*typedef struct { /*typedef struct {
@ -63,7 +63,8 @@ static int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
,.ADC_min = ADC_MIN_VAL \ ,.ADC_min = ADC_MIN_VAL \
,.ADC_max = ADC_MAX_VAL \ ,.ADC_max = ADC_MAX_VAL \
,.USART_speed = USART1_DEFAULT_SPEED \ ,.USART_speed = USART1_DEFAULT_SPEED \
,.strendRN = 0 \ ,.defflags = 0 \
,.NLfreeWarn = 100 \
} }
// change to placement // change to placement
@ -131,9 +132,6 @@ void flashstorage_init(){
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf)); memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
} }
currentlogidx = binarySearch(0, maxLnum-2, (uint8_t*)logsstart, sizeof(event_log)); currentlogidx = binarySearch(0, maxLnum-2, (uint8_t*)logsstart, sizeof(event_log));
SEND("\ncurrentconfidx="); printu(1, currentconfidx);
SEND("\ncurrentlogidx="); printu(1, currentlogidx);
newline();
} }
// store new configuration // store new configuration
@ -144,28 +142,42 @@ int store_userconf(){
if(currentconfidx > maxCnum - 3){ // there's no more place if(currentconfidx > maxCnum - 3){ // there's no more place
currentconfidx = 0; currentconfidx = 0;
DBG("Need to erase flash!"); DBG("Need to erase flash!");
if(erase_flash(Flash_Data, &__varsend)) return 1; if(erase_flash(Flash_Data, logsstart)) return 1;
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing) }else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
SEND("store_userconf\n");
SEND("\ncurrentconfidx="); printu(1, currentconfidx);
newline();
return write2flash(&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf)); return write2flash(&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
} }
/** /**
* @brief store_log - save log record L into flash memory * @brief store_log - save log record L into flash memory
* @param L - event log * @param L - event log (or NULL to delete flash)
* @return 0 if all OK * @return 0 if all OK
*/ */
int store_log(event_log *L){ int store_log(event_log *L){
if(!L){
currentlogidx = -1;
return erase_flash(logsstart, NULL);
}
if(currentlogidx > maxLnum - 3){ // there's no more place if(currentlogidx > maxLnum - 3){ // there's no more place
currentlogidx = 0; /*currentlogidx = 0;
DBG("Need to erase flash!"); DBG("Need to erase flash!");
if(erase_flash(logsstart, NULL)) return 1; if(erase_flash(logsstart, NULL)) return 1;*/
// prevent automatic logs erasing!
USB_send("\n\nERROR!\nCan't save logs: delete old manually!!!\n");
return 1;
}else ++currentlogidx; // take next data position (0 - within first run after firmware flashing) }else ++currentlogidx; // take next data position (0 - within first run after firmware flashing)
SEND("sore_log\n"); // put warning if there's little space
SEND("\ncurrentlogidx="); printu(1, currentlogidx); if(currentlogidx + the_conf.NLfreeWarn > maxLnum - 3){
newline(); uint32_t nfree = maxLnum - 2 - currentlogidx;
USB_send("\n\nWARNING!\nCan store only ");
USB_send(u2str(nfree));
USB_send(" logs!\n\n");
}
/*
USB_send("Stored #"); USB_send(u2str(currentlogidx));
USB_send(", max="); USB_send(u2str(maxLnum));
USB_send(", warn="); USB_send(u2str(the_conf.NLfreeWarn));
USB_send("\n");
*/
return write2flash(&logsstart[currentlogidx], L, sizeof(event_log)); return write2flash(&logsstart[currentlogidx], L, sizeof(event_log));
} }
@ -177,11 +189,14 @@ newline();
*/ */
int dump_log(int start, int Nlogs){ int dump_log(int start, int Nlogs){
if(currentlogidx < 0) return 1; if(currentlogidx < 0) return 1;
if(start < 0) start += currentlogidx; if(start < 0){
start += currentlogidx + 1;
if(start < 0) start = 0;
}
if(start > currentlogidx) return 1; if(start > currentlogidx) return 1;
int nlast; int nlast;
if(Nlogs > 0){ if(Nlogs > 0){
nlast = start + Nlogs; nlast = start + Nlogs - 1;
if(nlast > currentlogidx) nlast = currentlogidx; if(nlast > currentlogidx) nlast = currentlogidx;
}else nlast = currentlogidx; }else nlast = currentlogidx;
++nlast; ++nlast;

View File

@ -36,10 +36,10 @@
*/ */
typedef struct __attribute__((packed, aligned(4))){ typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number" uint16_t userconf_sz; // "magick number"
uint16_t NLfreeWarn; // warn user when there's less free log records than NLfreeWarn
int16_t ADC_min; // min&max values of ADC (shot when ADval > ADC_min && < ADC_max) int16_t ADC_min; // min&max values of ADC (shot when ADval > ADC_min && < ADC_max)
int16_t ADC_max; // !!! BOTH ARE SIGNED! so you can include 0 & 4096 int16_t ADC_max; // !!! BOTH ARE SIGNED! so you can include 0 & 4096
uint8_t trigstate; // level in `triggered` state uint8_t trigstate; // level in `triggered` state
uint8_t strendRN; // strings ends with "\r\n" instead of normal "\n"
uint8_t defflags; // default flags uint8_t defflags; // default flags
uint32_t dist_min; // minimal distance for LIDAR uint32_t dist_min; // minimal distance for LIDAR
uint32_t dist_max; // maximal -//- uint32_t dist_max; // maximal -//-
@ -48,7 +48,10 @@ typedef struct __attribute__((packed, aligned(4))){
} user_conf; } user_conf;
// values for user_conf.defflags: // values for user_conf.defflags:
// save events in flash
#define FLAG_SAVE_EVENTS (1 << 0) #define FLAG_SAVE_EVENTS (1 << 0)
// strings ends with "\r\n" instead of normal "\n"
#define FLAG_STRENDRN (1 << 1)
/* /*
* struct to save events logs * struct to save events logs
@ -64,7 +67,10 @@ typedef struct __attribute__((packed, aligned(4))){
extern user_conf the_conf; extern user_conf the_conf;
extern const user_conf *Flash_Data; extern const user_conf *Flash_Data;
extern const event_log *logsstart; extern const event_log *logsstart;
extern uint32_t _varslen, __varsstart, __varsend, __logsstart; extern int maxCnum, maxLnum;
// data from ld-file
extern uint32_t _varslen, __varsstart, __logsstart;
void flashstorage_init(); void flashstorage_init();
int store_userconf(); int store_userconf();

View File

@ -183,7 +183,7 @@ static char *get_USB(){
USB_send(curptr); // echo USB_send(curptr); // echo
//USB_send("ENDOINPUT\n"); //USB_send("ENDOINPUT\n");
//if(x == 1 && *curptr < 32){USB_send("\n"); USB_send(u2str(*curptr)); USB_send("\n");} //if(x == 1 && *curptr < 32){USB_send("\n"); USB_send(u2str(*curptr)); USB_send("\n");}
if(curptr[x-1] == '\n' || curptr[x-1] == '\r'){ if(curptr[x-1] == '\n'){ // || curptr[x-1] == '\r'){
curptr = tmpbuf; curptr = tmpbuf;
rest = USBBUF; rest = USBBUF;
// omit empty lines // omit empty lines

View File

@ -78,7 +78,18 @@ SECTIONS {
.myvars : .myvars :
{ {
. = ALIGN(1024); . = ALIGN(1024);
KEEP(*(.myvars)) __varsstart = ABSOLUTE(.);
KEEP(*(.myvars));
. = . + 2000;
. = ALIGN(1024);
__varsend = ABSOLUTE(.);
} > rom
.logs :
{
. = ALIGN(1024);
__logsstart = ABSOLUTE(.);
KEEP(*(.logs))
} > rom } > rom
_ldata = LOADADDR(.data); _ldata = LOADADDR(.data);
@ -95,3 +106,4 @@ SECTIONS {
} }
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
PROVIDE(_varslen = __varsend - __varsstart);

View File

@ -86,12 +86,14 @@ static void showuserconf(){
USB_send("}"); USB_send("}");
USB_send("\nUSART1SPD="); sendu(the_conf.USART_speed); USB_send("\nUSART1SPD="); sendu(the_conf.USART_speed);
USB_send("\nSTREND="); USB_send("\nSTREND=");
if(the_conf.strendRN) USB_send("RN"); if(the_conf.defflags & FLAG_STRENDRN) USB_send("RN");
else USB_send("N"); else USB_send("N");
uint8_t f = the_conf.defflags; uint8_t f = the_conf.defflags;
USB_send("\nSAVE_EVENTS="); USB_send("\nSAVE_EVENTS=");
if(f & FLAG_SAVE_EVENTS) USB_send("1"); if(f & FLAG_SAVE_EVENTS) USB_send("1");
else USB_send("0"); else USB_send("0");
USB_send("\nNFREE=");
sendu(the_conf.NLfreeWarn);
USB_send("\n"); USB_send("\n");
} }
@ -114,25 +116,27 @@ int parse_USBCMD(char *cmd){
CMD_ADCMIN " - min -//- (triggered when ADval>min & <max)\n" CMD_ADCMIN " - min -//- (triggered when ADval>min & <max)\n"
CMD_GETADCVAL " - get ADC value\n" CMD_GETADCVAL " - get ADC value\n"
CMD_BUZZER "S - turn buzzer ON/OFF\n" CMD_BUZZER "S - turn buzzer ON/OFF\n"
CMD_DELLOGS " - delete logs from flash memory\n"
CMD_DISTMIN " - min distance threshold (cm)\n" CMD_DISTMIN " - min distance threshold (cm)\n"
CMD_DISTMAX " - max distance threshold (cm)\n" CMD_DISTMAX " - max distance threshold (cm)\n"
CMD_DUMP " - dump stored events\n" CMD_DUMP "N - dump 20 last stored events (no x), all (x<1) or x\n"
CMD_FLASH " - FLASH info\n" CMD_FLASH " - FLASH info\n"
CMD_GPSRESTART " - send Full Cold Restart to GPS\n" CMD_GPSRESTART " - send Full Cold Restart to GPS\n"
CMD_GPSSTAT " - get GPS status\n" CMD_GPSSTAT " - get GPS status\n"
CMD_GPSSTR " - current GPS data string\n" CMD_GPSSTR " - current GPS data string\n"
CMD_LEDS "S - turn leds on/off (1/0)\n" CMD_LEDS "S - turn leds on/off (1/0)\n"
CMD_GETMCUTEMP " - MCU temperature\n" CMD_GETMCUTEMP " - MCU temperature\n"
CMD_SHOWCONF " - show current configuration\n" CMD_NFREE " - warn when free logs space less than this number (0 - not warn)"
CMD_PRINTTIME " - print time\n" CMD_PRINTTIME " - print time\n"
CMD_RESET " - reset MCU\n" CMD_RESET " - reset MCU\n"
CMD_SAVEEVTS "x - save/don't save (1/0) trigger events into flash\n" CMD_SAVEEVTS "S - save/don't save (1/0) trigger events into flash\n"
CMD_SHOWCONF " - show current configuration\n"
CMD_STORECONF " - store new configuration in flash\n" CMD_STORECONF " - store new configuration in flash\n"
CMD_STREND "x - string ends with \\n (x=n) or \\r\\n (x=r)\n" CMD_STREND "C - string ends with \\n (C=n) or \\r\\n (C=r)\n"
CMD_TRIGLVL "NS - working trigger N level S\n" CMD_TRIGLVL "NS - working trigger N level S\n"
CMD_TRGPAUSE "NP - pause (P, ms) after trigger N shots\n" CMD_TRGPAUSE "NP - pause (P, ms) after trigger N shots\n"
CMD_TRGTIME "N - show last trigger N time\n" CMD_TRGTIME "N - show last trigger N time\n"
CMD_USARTSPD "V - set USART1 speed to V\n" CMD_USARTSPD "N - set USART1 speed to N\n"
CMD_GETVDD " - Vdd value\n" CMD_GETVDD " - Vdd value\n"
); );
}else if(CMP(cmd, CMD_PRINTTIME) == 0){ }else if(CMP(cmd, CMD_PRINTTIME) == 0){
@ -168,21 +172,7 @@ int parse_USBCMD(char *cmd){
} }
}else if(CMP(cmd, CMD_GPSSTR) == 0){ // show GPS status string }else if(CMP(cmd, CMD_GPSSTR) == 0){ // show GPS status string
showGPSstr = 1; showGPSstr = 1;
}/* }else if(CMP(cmd, CMD_TRIGLVL) == 0){
else if(CMP(cmd, CMD_PULLUP) == 0){
DBG("Pullups");
cmd += sizeof(CMD_PULLUP) - 1;
uint8_t Nt = *cmd++ - '0';
if(Nt > TRIGGERS_AMOUNT - 1) goto bad_number;
uint8_t state = *cmd -'0';
if(state > 1) goto bad_number;
uint8_t oldval = the_conf.trig_pullups;
if(!state) the_conf.trig_pullups = oldval & ~(1<<Nt);
else the_conf.trig_pullups = oldval | (1<<Nt);
if(oldval != the_conf.trig_pullups) conf_modified = 1;
succeed = 1;
} */
else if(CMP(cmd, CMD_TRIGLVL) == 0){
DBG("Trig levels"); DBG("Trig levels");
cmd += sizeof(CMD_TRIGLVL) - 1; cmd += sizeof(CMD_TRIGLVL) - 1;
uint8_t Nt = *cmd++ - '0'; uint8_t Nt = *cmd++ - '0';
@ -315,8 +305,8 @@ int parse_USBCMD(char *cmd){
}else if(CMP(cmd, CMD_STREND) == 0){ }else if(CMP(cmd, CMD_STREND) == 0){
char c = cmd[sizeof(CMD_STREND) - 1]; char c = cmd[sizeof(CMD_STREND) - 1];
succeed = 1; succeed = 1;
if(c == 'n' || c == 'N') the_conf.strendRN = 0; if(c == 'n' || c == 'N') the_conf.defflags &= ~FLAG_STRENDRN;
else if(c == 'r' || c == 'R') the_conf.strendRN = 1; else if(c == 'r' || c == 'R') the_conf.defflags |= FLAG_STRENDRN;
else{ else{
succeed = 0; succeed = 0;
USB_send("Bad letter, should be 'n' or 'r'\n"); USB_send("Bad letter, should be 'n' or 'r'\n");
@ -325,24 +315,39 @@ int parse_USBCMD(char *cmd){
USB_send("FLASHSIZE="); USB_send("FLASHSIZE=");
sendu(FLASH_SIZE); sendu(FLASH_SIZE);
USB_send("kB\nFLASH_BASE="); USB_send("kB\nFLASH_BASE=");
sendu(FLASH_BASE); USB_send(u2hex(FLASH_BASE));
USB_send("\nFlash_Data="); USB_send("\nFlash_Data=");
sendu((uint32_t)Flash_Data); USB_send(u2hex((uint32_t)Flash_Data));
USB_send("\nvarslen="); USB_send("\nvarslen=");
sendu((uint32_t)&_varslen); sendu((uint32_t)&_varslen);
USB_send("\nvarsend="); USB_send("\nCONFsize=");
sendu((uint32_t)&__varsend); sendu(sizeof(user_conf));
USB_send("\nvarsstart="); USB_send("\nNconf_records=");
sendu((uint32_t)&__varsstart); sendu(maxCnum - 1);
USB_send("\nlogsstart="); USB_send("\nlogsstart=");
sendu((uint32_t)logsstart); USB_send(u2hex((uint32_t)logsstart));
USB_send("\nLOGsize=");
sendu(sizeof(event_log));
USB_send("\nNlogs_records=");
sendu(maxLnum - 1);
USB_send("\n"); USB_send("\n");
}else if(CMP(cmd, CMD_SAVEEVTS) == 0){ }else if(CMP(cmd, CMD_SAVEEVTS) == 0){
if('0' == cmd[sizeof(CMD_SAVEEVTS) - 1]) the_conf.defflags &= ~FLAG_SAVE_EVENTS; if('0' == cmd[sizeof(CMD_SAVEEVTS) - 1]) the_conf.defflags &= ~FLAG_SAVE_EVENTS;
else the_conf.defflags |= FLAG_SAVE_EVENTS; else the_conf.defflags |= FLAG_SAVE_EVENTS;
succeed = 1; succeed = 1;
}else if(CMP(cmd, CMD_DUMP) == 0){ }else if(CMP(cmd, CMD_DUMP) == 0){
if(dump_log(0, -1)) USB_send("Event log empty!\n"); if(getnum(cmd+sizeof(CMD_DUMP)-1, &N)) N = -20; // default - without N
else N = -N;
if(N > 0) N = 0;
if(dump_log(N, -1)) USB_send("Event log empty!\n");
}else if(CMP(cmd, CMD_NFREE) == 0){
GETNUM(CMD_NFREE);
if(N < 0 || N > 0xffff) goto bad_number;
the_conf.NLfreeWarn = (uint16_t)N;
succeed = 1;
}else if(CMP(cmd, CMD_DELLOGS) == 0){
if(store_log(NULL)) USB_send("Error during erasing flash\n");
else USB_send("All logs erased\n");
}else return 1; }else return 1;
/*else if(CMP(cmd, CMD_) == 0){ /*else if(CMP(cmd, CMD_) == 0){
; ;
@ -433,3 +438,70 @@ char *strcp(char* dst, const char *src){
while((*dst++ = *src++)); while((*dst++ = *src++));
return dst - 1; return dst - 1;
} }
// read `buf` and get first integer `N` in it
// @return 0 if all OK or 1 if there's not a number; omit spaces and '='
int getnum(const char *buf, int32_t *N){
char c;
int positive = -1;
int32_t val = 0;
while((c = *buf++)){
if(c == '\t' || c == ' ' || c == '='){
if(positive < 0) continue; // beginning spaces
else break; // spaces after number
}
if(c == '-'){
if(positive < 0){
positive = 0;
continue;
}else break; // there already was `-` or number
}
if(c < '0' || c > '9') break;
if(positive < 0) positive = 1;
val = val * 10 + (int32_t)(c - '0');
}
if(positive != -1){
if(positive == 0){
if(val == 0) return 1; // single '-'
val = -val;
}
*N = val;
}else return 1;
return 0;
}
static char strbuf[11];
// return string buffer (strbuf) with val
char *u2str(uint32_t val){
char *bufptr = &strbuf[10];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
*(--bufptr) = val % 10 + '0';
val /= 10;
}
}
return bufptr;
}
// return strbuf filled with hex
char *u2hex(uint32_t val){
char *bufptr = strbuf;
*bufptr++ = '0';
*bufptr++ = 'x';
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
IWDG->KR = IWDG_REFRESH;
for(i = 0; i < 4; ++i, --ptr){
for(j = 1; j > -1; --j){
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) *bufptr++ = half + '0';
else *bufptr++ = half - 10 + 'a';
}
}
*bufptr = 0;
return strbuf;
}

View File

@ -47,11 +47,17 @@
#define CMD_RESET "reset" #define CMD_RESET "reset"
#define CMD_STREND "strend" #define CMD_STREND "strend"
#define CMD_FLASH "flash" #define CMD_FLASH "flash"
#define CMD_SAVEEVTS "saveevt" #define CMD_SAVEEVTS "se"
#define CMD_DUMP "dump" #define CMD_DUMP "dump"
#define CMD_NFREE "nfree"
#define CMD_DELLOGS "deletelogs"
extern uint8_t showGPSstr; extern uint8_t showGPSstr;
int getnum(const char *buf, int32_t *N);
char *u2str(uint32_t val);
char *u2hex(uint32_t val);
int strln(const char *s); int strln(const char *s);
char *strcp(char* dst, const char *src); char *strcp(char* dst, const char *src);
int cmpstr(const char *s1, const char *s2, int n); int cmpstr(const char *s1, const char *s2, int n);

View File

@ -19,8 +19,9 @@
#include "stm32f1.h" #include "stm32f1.h"
#include "flash.h" #include "flash.h"
#include "usart.h"
#include "lidar.h" #include "lidar.h"
#include "str.h"
#include "usart.h"
extern volatile uint32_t Tms; extern volatile uint32_t Tms;
static volatile int idatalen[4][2] = {0}; // received data line length (including '\n') static volatile int idatalen[4][2] = {0}; // received data line length (including '\n')
@ -252,22 +253,6 @@ void usart3_isr(){
} }
} }
// return string buffer with val
char *u2str(uint32_t val){
static char buf[11];
char *bufptr = &buf[10];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
*(--bufptr) = val % 10 + '0';
val /= 10;
}
}
return bufptr;
}
// print 32bit unsigned int // print 32bit unsigned int
void printu(int n, uint32_t val){ void printu(int n, uint32_t val){
usart_send(n, u2str(val)); usart_send(n, u2str(val));
@ -275,17 +260,7 @@ void printu(int n, uint32_t val){
// print 32bit unsigned int as hex // print 32bit unsigned int as hex
void printuhex(int n, uint32_t val){ void printuhex(int n, uint32_t val){
usart_send(n, "0x"); usart_send(n, u2hex(val));
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
IWDG->KR = IWDG_REFRESH;
for(i = 0; i < 4; ++i, --ptr){
for(j = 1; j > -1; --j){
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(n, half + '0');
else usart_putchar(n, half - 10 + 'a');
}
}
} }
#ifdef EBUG #ifdef EBUG
@ -326,34 +301,3 @@ void dma1_channel2_isr(){ // USART3
txrdy[3] = 1; txrdy[3] = 1;
} }
} }
// read `buf` and get first integer `N` in it
// @return 0 if all OK or 1 if there's not a number; omit spaces and '='
int getnum(const char *buf, int32_t *N){
char c;
int positive = -1;
int32_t val = 0;
while((c = *buf++)){
if(c == '\t' || c == ' ' || c == '='){
if(positive < 0) continue; // beginning spaces
else break; // spaces after number
}
if(c == '-'){
if(positive < 0){
positive = 0;
continue;
}else break; // there already was `-` or number
}
if(c < '0' || c > '9') break;
if(positive < 0) positive = 1;
val = val * 10 + (int32_t)(c - '0');
}
if(positive != -1){
if(positive == 0){
if(val == 0) return 1; // single '-'
val = -val;
}
*N = val;
}else return 1;
return 0;
}

View File

@ -55,10 +55,8 @@ void usarts_setup();
int usart_getline(int n, char **line); int usart_getline(int n, char **line);
void usart_send(int n, const char *str); void usart_send(int n, const char *str);
void usart_putchar(int n, char ch); void usart_putchar(int n, char ch);
char *u2str(uint32_t val);
void printu(int n, uint32_t val); void printu(int n, uint32_t val);
void printuhex(int n, uint32_t val); void printuhex(int n, uint32_t val);
int getnum(const char *buf, int32_t *N);
#if defined EBUG || defined USART1PROXY #if defined EBUG || defined USART1PROXY
void newline(); void newline();

View File

@ -115,7 +115,7 @@ void USB_send(const char *buf){
uint16_t proc = 0, s = (l > USB_TXBUFSZ - 1) ? USB_TXBUFSZ - 1: l; uint16_t proc = 0, s = (l > USB_TXBUFSZ - 1) ? USB_TXBUFSZ - 1: l;
for(int i = 0; i < s; ++i, ++proc){ for(int i = 0; i < s; ++i, ++proc){
char c = buf[ctr+proc]; char c = buf[ctr+proc];
if(c == '\n' && the_conf.strendRN){ // add '\r' before '\n' if(c == '\n' && the_conf.defflags & FLAG_STRENDRN){ // add '\r' before '\n'
tmpbuf[i++] = '\r'; tmpbuf[i++] = '\r';
if(i == s) ++s; if(i == s) ++s;
} }