diff --git a/F3:F303/NitrogenFlooding/Makefile b/F3:F303/NitrogenFlooding/Makefile index eb27ee2..a4468d2 100644 --- a/F3:F303/NitrogenFlooding/Makefile +++ b/F3:F303/NitrogenFlooding/Makefile @@ -4,6 +4,7 @@ MCU := F302xc # change this linking script depending on particular MCU model, LDSCRIPT := stm32f302xB.ld DEFINES := -DUSB1_16 +LDADD := -lm include ../makefile.f3 include ../../makefile.stm32 diff --git a/F3:F303/NitrogenFlooding/Readme.md b/F3:F303/NitrogenFlooding/Readme.md index 063860b..4b84c25 100644 --- a/F3:F303/NitrogenFlooding/Readme.md +++ b/F3:F303/NitrogenFlooding/Readme.md @@ -59,7 +59,7 @@ Automated liquid nitrogen flooding machine | 48 | PB11 | SCRN RST | slow out | Screen reset | | 49 | (VSS) | | | | | 50 | (VDD) | | | | -| 51 | PB12 | SCRN NSS | slow out | Screen activate | +| 51 | PB12 | SCRN LED | slow out | Screen LEDs on | | 52 | PB13 | SCRN SCK | AF5 | SPI for screen | | 53 | PB14 | SCRN MISO | AF5 | | | 54 | PB15 | SCRN MOSI | AF5 | | @@ -143,7 +143,7 @@ Automated liquid nitrogen flooding machine | 96 | PB9 | - | - | | | 47 | PB10 | SCRN DCRS | slow out | Screen data/cmd | | 48 | PB11 | SCRN RST | slow out | Screen reset | -| 51 | PB12 | SCRN NSS | slow out | Screen activate | +| 51 | PB12 | SCRN LED | slow out | Screen LEDs on | | 52 | PB13 | SCRN SCK | AF5 | SPI for screen | | 53 | PB14 | SCRN MISO | AF5 | | | 54 | PB15 | SCRN MOSI | AF5 | | @@ -208,6 +208,8 @@ Automated liquid nitrogen flooding machine ### DMA1 - Channel 1 - ADC1 +- Channel 4 - SPI2 Rx +- Channel 5 - SPI2 Tx - Channel 6 - I2C1 Tx - Channel 7 - I2C1 Rx diff --git a/F3:F303/NitrogenFlooding/hardware.c b/F3:F303/NitrogenFlooding/hardware.c index f644ce2..420c181 100644 --- a/F3:F303/NitrogenFlooding/hardware.c +++ b/F3:F303/NitrogenFlooding/hardware.c @@ -18,6 +18,7 @@ #include "hardware.h" #include "i2c.h" +#include "spi.h" int LEDsON = 1; @@ -47,10 +48,10 @@ TRUE_INLINE void gpio_setup(){ GPIOB->AFR[0] = AFRf(4, 6) | AFRf(4, 7); GPIOB->AFR[1] = AFRf(5, 13) | AFRf(5, 14) | AFRf(5, 15); GPIOB->MODER = MODER_O(0) | MODER_AF(6) | MODER_AF(7) | MODER_O(10) | MODER_O(11) | MODER_O(12) | MODER_AF(13) - | MODER_AF(14) | MODER_AF(15); - GPIOB->OSPEEDR = OSPEED_HI(6) | OSPEED_HI(7) | OSPEED_MED(13) | OSPEED_MED(14) | OSPEED_MED(15); + | MODER_AF(14) | MODER_AF(15); // 10-DC, 11-RST, 12-LED, 13-SCK, 14-MISO, 15-MOSI + GPIOB->OSPEEDR = OSPEED_HI(6) | OSPEED_HI(7) | OSPEED_HI(13) | OSPEED_HI(14) | OSPEED_HI(15); GPIOB->OTYPER = 0; - GPIOB->PUPDR = 0; + GPIOB->PUPDR = PUPD_PU(14); // PU MISO // PORT C //GPIOC->ODR = 0; @@ -134,7 +135,8 @@ TRUE_INLINE void iwdg_setup(){ void hw_setup(){ RCC->AHBENR |= RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN; gpio_setup(); - i2c_setup(HIGH_SPEED); + i2c_setup(LOW_SPEED); + spi_setup(); pwm_setup(); #ifndef EBUG iwdg_setup(); diff --git a/F3:F303/NitrogenFlooding/hardware.h b/F3:F303/NitrogenFlooding/hardware.h index 986a517..bfbbaa2 100644 --- a/F3:F303/NitrogenFlooding/hardware.h +++ b/F3:F303/NitrogenFlooding/hardware.h @@ -49,6 +49,21 @@ #define LED_on(x) do{if(LEDsON) pin_clear(LEDs_port, 1<<(8+x));}while(0) #define LED_get(x) (LEDs_port->IDR & 1<<(8+x) ? 0 : 1) +// screen LEDon/off - PB12; reset - PB11; data/command - PB10 +#define SCRN_LED_pin (1<<12) +#define SCRN_LED_port (GPIOB) +#define SCRN_LED_set(a) do{if(a) pin_set(SCRN_LED_port, SCRN_LED_pin); else pin_clear(SCRN_LED_port, SCRN_LED_pin);}while(0) +#define SCRN_LED_get() (SCRN_LED_port->IDR & SCRN_LED_pin ? 1: 0) +#define SCRN_RST_pin (1<<11) +#define SCRN_RST_port (GPIOB) +#define SCRN_RST_set(a) do{if(a) pin_set(SCRN_RST_port, SCRN_RST_pin); else pin_clear(SCRN_RST_port, SCRN_RST_pin);}while(0) +#define SCRN_RST_get() (SCRN_RST_port->IDR & SCRN_RST_pin ? 1: 0) +#define SCRN_DCX_pin (1<<10) +#define SCRN_DCX_port (GPIOB) +#define SCRN_DCX_get() (SCRN_DCX_port->IDR & SCRN_DCX_pin ? 1: 0) +#define SCRN_Data() do{pin_set(SCRN_DCX_port, SCRN_DCX_pin);}while(0) +#define SCRN_Command() do{pin_clear(SCRN_DCX_port, SCRN_DCX_pin);}while(0) + // Buttons amount #define BTNSNO (7) #define BTNs_port GPIOD diff --git a/F3:F303/NitrogenFlooding/i2c.c b/F3:F303/NitrogenFlooding/i2c.c index 41e85c9..881577a 100644 --- a/F3:F303/NitrogenFlooding/i2c.c +++ b/F3:F303/NitrogenFlooding/i2c.c @@ -42,7 +42,7 @@ static uint8_t I2Cbuf[256], i2cbuflen = 0; // buffer for DMA tx/rx and its len static inline int isI2Cbusy(){ cntr = Tms; do{ - if(Tms - cntr > I2C_TIMEOUT){ USND("Timeout, DMA transfer in progress?\n"); return 1;} + if(Tms - cntr > I2C_TIMEOUT){ USND("Timeout, DMA transfer in progress?"); return 1;} }while(I2Cbusy); return 0; } @@ -103,7 +103,7 @@ static uint8_t i2c_start(uint8_t busychk){ while(I2C1->ISR & I2C_ISR_BUSY){ IWDG->KR = IWDG_REFRESH; if(Tms - cntr > I2C_TIMEOUT){ - USND("Line busy\n"); + USND("Line busy"); return 0; // check busy }} } @@ -111,7 +111,7 @@ static uint8_t i2c_start(uint8_t busychk){ while(I2C1->CR2 & I2C_CR2_START){ IWDG->KR = IWDG_REFRESH; if(Tms - cntr > I2C_TIMEOUT){ - USND("No start\n"); + USND("No start"); return 0; // check start }} return 1; @@ -143,11 +143,11 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t s IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ I2C1->ICR |= I2C_ICR_NACKCF; - //USND("NAK\n"); + DBG("NAK"); return 0; } if(Tms - cntr > I2C_TIMEOUT){ - //USND("Timeout\n"); + DBG("Timeout"); return 0; } } @@ -163,7 +163,10 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t s } uint8_t write_i2c(uint8_t addr, uint8_t *data, uint8_t nbytes){ - if(isI2Cbusy()) return 0; + if(isI2Cbusy()){ + DBG("I2C busy"); + return 0; + } return write_i2cs(addr, data, nbytes, 1); } @@ -203,11 +206,11 @@ static uint8_t read_i2cb(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t bu IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ I2C1->ICR |= I2C_ICR_NACKCF; - //USND("NAK\n"); + //DBG("NAK"); return 0; } if(Tms - cntr > I2C_TIMEOUT){ - //USND("Timeout\n"); + //DBG("Timeout"); return 0; } } @@ -250,22 +253,22 @@ uint8_t read_i2c_reg16(uint8_t addr, uint16_t reg16, uint8_t *data, uint8_t nbyt void i2c_init_scan_mode(){ i2caddr = 1; // start from 1 as 0 is a broadcast address I2C_scan_mode = 1; + DBG("init scan"); } // return 1 if next addr is active & return in as `addr` // if addresses are over, return 1 and set addr to I2C_NOADDR // if scan mode inactive, return 0 and set addr to I2C_NOADDR int i2c_scan_next_addr(uint8_t *addr){ - if(isI2Cbusy()) return 0; + if(isI2Cbusy()){ + DBG("scan: busy"); + return 0; + } *addr = i2caddr; if(i2caddr == I2C_ADDREND){ - *addr = I2C_ADDREND; I2C_scan_mode = 0; return 0; } - /*while(!u3txrdy); - USND("Addr: "); USND(uhex2str(i2caddr)); USND("\n"); - usart3_sendbuf();*/ uint8_t byte; if(!read_i2c((i2caddr++)<<1, &byte, 1)) return 0; return 1; @@ -274,10 +277,10 @@ int i2c_scan_next_addr(uint8_t *addr){ // dump I2Cbuf void i2c_bufdudump(){ if(goterr){ - USND("Last transfer ends with error!\n"); + USND("Last transfer ends with error!"); goterr = 0; } - USND("I2C buffer:\n"); + USND("I2C buffer:"); hexdump(USB_sendstr, I2Cbuf, i2cbuflen); } diff --git a/F3:F303/NitrogenFlooding/main.c b/F3:F303/NitrogenFlooding/main.c index f29f1dc..4638c7a 100644 --- a/F3:F303/NitrogenFlooding/main.c +++ b/F3:F303/NitrogenFlooding/main.c @@ -17,12 +17,14 @@ */ #include "adc.h" +#include "BMP280.h" //#include "buttons.h" //#include "can.h" //#include "flash.h" #include "hardware.h" #include "i2c.h" #include "proto.h" +#include "strfunc.h" #include "usb.h" #define MAXSTRLEN RBINSZ @@ -47,6 +49,7 @@ int main(void){ USB_setup(); //CAN_setup(the_conf.CANspeed); adc_setup(); + BMP280_setup(0); USBPU_ON(); uint32_t ctr = 0; // CAN_message *can_mesg; @@ -86,7 +89,23 @@ int main(void){ USB_sendstr(") - found device\n"); } } - i2c_have_DMA_Rx(); // check if there's DMA Rx complete + //i2c_have_DMA_Rx(); // check if there's DMA Rx complete + BMP280_process(); + BMP280_status s = BMP280_get_status(); + if(s == BMP280_RDY){ // data ready - get it + float T, P, H; + if(BMP280_getdata(&T, &P, &H)){ + USB_sendstr("T="); USB_sendstr(float2str(T, 2)); USB_sendstr("\nP="); + USB_sendstr(float2str(P, 1)); + P *= 0.00750062f; USB_sendstr("\nPmm="); USB_sendstr(float2str(P, 1)); + USB_sendstr("\nH="); USB_sendstr(float2str(H, 1)); + USB_sendstr("\nTdew="); USB_sendstr(float2str(Tdew(T, H), 1)); + newline(); + }else USB_sendstr("Can't read data\n"); + }else if(s == BMP280_ERR){ + USB_sendstr("BME280 error\n"); + BMP280_init(); + } int l = USB_receivestr(inbuff, MAXSTRLEN); if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n"); else if(l){ diff --git a/F3:F303/NitrogenFlooding/nitrogen.bin b/F3:F303/NitrogenFlooding/nitrogen.bin index 26b440d..ffeaab0 100755 Binary files a/F3:F303/NitrogenFlooding/nitrogen.bin and b/F3:F303/NitrogenFlooding/nitrogen.bin differ diff --git a/F3:F303/NitrogenFlooding/nitrogen.files b/F3:F303/NitrogenFlooding/nitrogen.files index 0b934c7..a6753f2 100644 --- a/F3:F303/NitrogenFlooding/nitrogen.files +++ b/F3:F303/NitrogenFlooding/nitrogen.files @@ -1,3 +1,5 @@ +BMP280.c +BMP280.h adc.c adc.h buttons.c @@ -16,6 +18,8 @@ hashgen/hdr.h hashgen/test.c i2c.c i2c.h +ili9341.c +ili9341.h main.c pdnuart.c pdnuart.h @@ -23,6 +27,8 @@ proto.c proto.h ringbuffer.c ringbuffer.h +spi.c +spi.h steppers.c steppers.h strfunc.c diff --git a/F3:F303/NitrogenFlooding/proto.c b/F3:F303/NitrogenFlooding/proto.c index e9c86e9..6ac418c 100644 --- a/F3:F303/NitrogenFlooding/proto.c +++ b/F3:F303/NitrogenFlooding/proto.c @@ -17,9 +17,11 @@ */ #include "adc.h" +#include "BMP280.h" #include "hardware.h" #include "i2c.h" #include "proto.h" +#include "ili9341.h" #include "strfunc.h" #include "version.inc" @@ -37,21 +39,30 @@ static int goodstub(const char *cmd, int parno, const char *carg, int32_t iarg){ return RET_GOOD; } +// send over USB cmd[parno][=i] static void sendkey(const char *cmd, int parno, int32_t i){ USB_sendstr(cmd); if(parno > -1) USB_sendstr(u2str((uint32_t)parno)); USB_putbyte('='); USB_sendstr(i2str(i)); newline(); } +// `sendkey` for floating parameter static void sendkeyf(const char *cmd, int parno, float f){ USB_sendstr(cmd); if(parno > -1) USB_sendstr(u2str((uint32_t)parno)); USB_putbyte('='); USB_sendstr(float2str(f, 2)); newline(); } +// `sendkey` for uint32_t static void sendkeyu(const char *cmd, int parno, uint32_t u){ USB_sendstr(cmd); if(parno > -1) USB_sendstr(u2str((uint32_t)parno)); USB_putbyte('='); USB_sendstr(u2str(u)); newline(); } +// `sendkey` for uint32_t out in hex +static void sendkeyuhex(const char *cmd, int parno, uint32_t u){ + USB_sendstr(cmd); + if(parno > -1) USB_sendstr(u2str((uint32_t)parno)); + USB_putbyte('='); USB_sendstr(uhex2str(u)); newline(); +} static int leds(const char *cmd, int parno, const char *c, int32_t i){ if(parno < 0){ // enable/disable all @@ -72,6 +83,30 @@ static int leds(const char *cmd, int parno, const char *c, int32_t i){ return RET_GOOD; } +static int bme(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t _U_ i){ + if(BMP280_get_status() == BMP280_NOTINIT){ + DBG("Need 2 init"); + if(!BMP280_init()){ + USND("Can't init"); + return RET_BAD; + } + } + if(!BMP280_start()) return RET_BAD; + return RET_GOOD; +} + +static int bmefilter(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t _U_ i){ + BMP280_Filter f = BMP280_FILTER_OFF; + if(c){ + if(i < 0 || i >= BMP280_FILTERMAX) return RET_WRONGARG; + f = (BMP280_Filter) i; + BMP280_setfilter(f); + if(!BMP280_init()) return RET_BAD; + } + sendkey(cmd, -1, BMP280_getfilter()); + return RET_GOOD; +} + static int buzzer(const char *cmd, int _U_ parno, const char _U_ *c, int32_t i){ if(c){ if(i > 0) BUZZER_ON(); @@ -88,9 +123,29 @@ static int i2scan(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t static int i2addr(const char *cmd, int _U_ parno, const char *c, int32_t i){ if(c){ if(i < 0 || i>= I2C_ADDREND) return RET_WRONGARG; - I2Caddress = (uint8_t) i; + I2Caddress = ((uint8_t) i)<<1; } - sendkey(cmd, -1, I2Caddress); + sendkey(cmd, -1, I2Caddress>>1); + return RET_GOOD; +} +static int i2reg(const char *cmd, int parno, const char _U_ *c, int32_t i){ + if(parno < 0 || parno > 127) return RET_WRONGPARNO; + uint8_t d[2]; + if(c){ + if(i < 0 || i > 255) return RET_WRONGARG; + d[0] = parno; d[1] = (uint8_t)i; + if(!write_i2c(I2Caddress, d, 2)) return RET_BAD; + } + if(!read_i2c_reg(I2Caddress, (uint8_t)parno, d, 1)) return RET_BAD; + sendkey(cmd, parno, d[0]); + return RET_GOOD; +} +static int i2read(const char _U_ *cmd, int parno, const char _U_ *c, int32_t _U_ i){ + uint8_t buf[128]; + if(parno < 0 || parno > 128) return RET_WRONGPARNO; + if(!read_i2c(I2Caddress, buf, (uint8_t)parno)) return RET_BAD; + USB_sendstr("I2C got data:\n"); + hexdump(USB_sendstr, buf, parno); return RET_GOOD; } @@ -142,6 +197,45 @@ static int pwm(const char *cmd, int parno, const char *c, int32_t i){ return RET_GOOD; } +static int scrnled(const char *cmd, int _U_ parno, const char *c, int32_t i){ + if(c) SCRN_LED_set(i); + sendkeyu(cmd, -1, SCRN_LED_get()); + return RET_GOOD; +} +static int scrndcr(const char *cmd, int _U_ parno, const char *c, int32_t i){ + if(c){ + if(i) SCRN_Data(); + else SCRN_Command(); + } + sendkeyu(cmd, -1, SCRN_DCX_get()); + return RET_GOOD; +} +static int scrnrst(const char *cmd, int _U_ parno, const char *c, int32_t i){ + if(c) SCRN_RST_set(i); + sendkeyu(cmd, -1, SCRN_RST_get()); + return RET_GOOD; +} +static int scrnrdwr(const char *cmd, int parno, const char *c, int32_t i){ + if(parno < 0) return RET_WRONGPARNO; + if(c){ + if(i < 0 || i > 255) return RET_WRONGARG; + if(!ili9341_writereg(parno, (uint8_t*)&i, 1)) return RET_BAD; + } + i = 0; + if(!ili9341_readreg(parno, (uint8_t*)&i, 1)) return RET_BAD; + sendkeyu(cmd, parno, i); + return RET_GOOD; +} +static int scrnrdwr4(const char *cmd, int parno, const char *c, int32_t i){ + if(parno < 0) return RET_WRONGPARNO; + if(c){ + if(!ili9341_writereg(parno, (uint8_t*)&i, 4)) return RET_BAD; + } + if(!ili9341_readreg(parno, (uint8_t*)&i, 4)) return RET_BAD; + sendkeyuhex(cmd, parno, i); + return RET_GOOD; +} + typedef struct{ int (*fn)(const char*, int, const char*, int32_t); const char *cmd; @@ -151,6 +245,8 @@ typedef struct{ commands cmdlist[] = { {goodstub, "stub", "simple stub"}, {NULL, "Different commands", NULL}, + {bme, "BME", "get pressure, temperature and humidity"}, + {bmefilter, "BMEf", "set filter (0..4)"}, {buzzer, "buzzer", "get/set (0 - off, 1 - on) buzzer"}, {leds, "LED", "LEDx=y; where x=0..3 to work with single LED (then y=1-set, 0-reset, 2-toggle), absent to work with all (y=0 - disable, 1-enable)"}, {pwm, "pwm", "set/get x channel (0..3) pwm value (0..100)"}, @@ -158,7 +254,15 @@ commands cmdlist[] = { {tms, "tms", "print Tms"}, {NULL, "I2C commands", NULL}, {i2addr, "iicaddr", "set/get I2C address"}, + {i2read, "iicread", "read X (0..128) bytes"}, + {i2reg, "iicreg", "read/write I2C register"}, {i2scan, "iicscan", "scan I2C bus"}, + {NULL, "Screen commands", NULL}, + {scrnled, "Sled", "turn on/off screen lights"}, + {scrndcr, "Sdcr", "set data(1)/command(0)"}, + {scrnrst, "Srst", "reset (1/0)"}, + {scrnrdwr, "Sreg", "read/write 8-bit register"}, + {scrnrdwr4, "Sregx", "read/write 32-bit register"}, {NULL, "ADC commands", NULL}, {adcval, "ADC", "get ADCx value (without x - for all)"}, {adcvoltage, "ADCv", "get ADCx voltage (without x - for all)"}, diff --git a/F3:F303/NitrogenFlooding/strfunc.c b/F3:F303/NitrogenFlooding/strfunc.c index 8dca52b..140638a 100644 --- a/F3:F303/NitrogenFlooding/strfunc.c +++ b/F3:F303/NitrogenFlooding/strfunc.c @@ -272,7 +272,7 @@ const char *getint(const char *txt, int32_t *I){ static const float pwr10[] = {1.f, 10.f, 100.f, 1000.f, 10000.f}; static const float rounds[] = {0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f}; #define P10L (sizeof(pwr10)/sizeof(uint32_t) - 1) -const char *float2str(float x, uint8_t prec){ +char *float2str(float x, uint8_t prec){ static char str[16] = {0}; // -117.5494E-36\0 - 14 symbols max! if(prec > P10L) prec = P10L; if(isnan(x)){ memcpy(str, "NAN", 4); return str;} diff --git a/F3:F303/NitrogenFlooding/strfunc.h b/F3:F303/NitrogenFlooding/strfunc.h index 9c77a72..b4536d7 100644 --- a/F3:F303/NitrogenFlooding/strfunc.h +++ b/F3:F303/NitrogenFlooding/strfunc.h @@ -25,8 +25,8 @@ void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len); char *u2str(uint32_t val); char *i2str(int32_t i); char *uhex2str(uint32_t val); +char *float2str(float x, uint8_t prec); const char *getnum(const char *txt, uint32_t *N); const char *omit_spaces(const char *buf); const char *getint(const char *txt, int32_t *I); -const char *float2str(float x, uint8_t prec); //void mymemcpy(char *dest, const char *src, int len); diff --git a/F3:F303/NitrogenFlooding/version.inc b/F3:F303/NitrogenFlooding/version.inc index 1d5ece6..4d2cf81 100644 --- a/F3:F303/NitrogenFlooding/version.inc +++ b/F3:F303/NitrogenFlooding/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "56" -#define BUILD_DATE "2023-05-03" +#define BUILD_NUMBER "110" +#define BUILD_DATE "2023-05-08" diff --git a/F3:F303/inc/Fx/common_macros.h b/F3:F303/inc/Fx/common_macros.h index 8bdc4de..20b8535 100644 --- a/F3:F303/inc/Fx/common_macros.h +++ b/F3:F303/inc/Fx/common_macros.h @@ -40,6 +40,10 @@ #define NULL (0) #endif +#ifndef _U_ +#define _U_ __attribute__((__unused__)) +#endif + // some good things from CMSIS #define nop() __NOP() diff --git a/makefile.stm32 b/makefile.stm32 index d69ab20..6e51ee4 100644 --- a/makefile.stm32 +++ b/makefile.stm32 @@ -96,7 +96,7 @@ release: LDFLAGS += -flto release: $(TARGFILE) bin list size #debug: add debug flags -debug: CFLAGS += -DEBUG -Werror -g3 -gdwarf-2 +debug: CFLAGS += -DEBUG -Werror -g3 -gdwarf-2 debug: TARGET := DEBUG debug: $(TARGFILE) bin list size @@ -145,7 +145,7 @@ $(LIST): $(ELF) $(ELF): $(OBJDIR) $(OBJS) @echo " LD $(ELF)" - $(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF) + $(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF) $(LDADD) size: $(ELF) $(SIZE) $(ELF) @@ -158,6 +158,7 @@ clean: flash: $(BIN) @echo " FLASH $(BIN)" $(STFLASH) write $(BIN) 0x8000000 + $(STFLASH) reset boot: $(BIN) @echo " LOAD $(BIN) through bootloader"