diff --git a/F3:F303/PL2303/Makefile b/F3:F303/PL2303/Makefile index f725d8c..1903586 100644 --- a/F3:F303/PL2303/Makefile +++ b/F3:F303/PL2303/Makefile @@ -9,12 +9,8 @@ MCU ?= F303xb ARMARCH = __ARM_ARCH_7M__ # change this linking script depending on particular MCU model, LDSCRIPT ?= stm32f303xB.ld -# debug -#DEFS = -DEBUG -INDEPENDENT_HEADERS= - -FP_FLAGS ?= -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -fsingle-precision-constant -mlittle-endian -DARM_MATH_CM4 +FP_FLAGS ?= -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -mlittle-endian -DARM_MATH_CM4 ASM_FLAGS ?= -mthumb -mcpu=cortex-m4 ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS) -D $(ARMARCH) @@ -42,6 +38,10 @@ DFUUTIL := $(shell which dfu-util) ############################################################################### # Source files OBJDIR := mk +# target (debug/release) +TARGFILE := $(OBJDIR)/TARGET +# autoincremental version & build date +VERSION_FILE = version.inc SRC := $(wildcard *.c) OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) STARTUP := $(OBJDIR)/startup.o @@ -59,16 +59,15 @@ LIB_DIR := $(INC_DIR)/ld # C flags CFLAGS += -g -gdwarf-2 # debuggin symbols in listing CFLAGS += -O2 -D__thumb2__=1 -MD -CFLAGS += -Wall -Werror -Wextra -Wshadow +CFLAGS += -Wall -Wextra -Wshadow CFLAGS += -fshort-enums -ffunction-sections -fdata-sections -#CFLAGS += -fno-common -ffunction-sections -fdata-sections -fno-stack-protector +#CFLAGS += -fno-common -fno-stack-protector CFLAGS += $(ARCH_FLAGS) ############################################################################### # Linker flags -#LDFLAGS += -nostartfiles --static -nostdlib -specs=nosys.specs -specs=nano.specs +LDFLAGS += -nostartfiles --static -specs=nosys.specs -specs=nano.specs LDFLAGS += $(ARCH_FLAGS) -LDFLAGS += -specs=nano.specs -specs=nosys.specs LDFLAGS += -L$(LIB_DIR) #-L$(TOOLCHLIB) LDFLAGS += -T$(LDSCRIPT) @@ -76,7 +75,7 @@ LDFLAGS += -Wl,-Map=$(MAP),--cref -Wl,--gc-sections -Wl,--print-memory-usage ############################################################################### # Used libraries -#LDLIBS += -lc $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LDLIBS += -lm -lc $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU) @@ -85,7 +84,36 @@ LIST := $(OBJDIR)/$(BINARY).list BIN := $(BINARY).bin HEX := $(BINARY).hex -all: bin list size +ifeq ($(shell test -e $(TARGFILE) && echo -n yes),yes) + TARGET := $(file < $(TARGFILE)) +else + TARGET := RELEASE +endif + +ifeq ($(TARGET), DEBUG) + .DEFAULT_GOAL := debug +endif + +ifeq ($(shell test -e $(VERSION_FILE) && echo -n yes), yes) + NEXTVER := $(shell expr $$(awk '/#define BUILD_NUMBER/' $(VERSION_FILE) | tr -cd "[0-9]") + 1) +else + NEXTVER := "1" +endif +BUILDDATE := $(shell date +%Y-%m-%d) + +# release: add LTO +release: CFLAGS += -flto +release: LDFLAGS += -flto +release: $(TARGFILE) bin list size + +#debug: add debug flags +debug: CFLAGS += -DEBUG -Werror -g3 +debug: TARGET := DEBUG +debug: $(TARGFILE) bin list size + +$(TARGFILE): $(OBJDIR) + @echo -e "\t\tTARGET: $(TARGET)" + @echo "$(TARGET)" > $(TARGFILE) elf: $(ELF) bin: $(BIN) @@ -102,6 +130,14 @@ $(OBJDIR): $(STARTUP): $(INC_DIR)/startup/vector.c $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $< +$(VERSION_FILE): *.[ch] + @[ -f $(VERSION_FILE) ] || echo -e "#define BUILD_NUMBER \"0\"\n#define BUILD_DATE \"none\"" > $(VERSION_FILE) + @echo " Generate version: $(NEXTVER) for date $(BUILDDATE)" + @sed -i "s/#define BUILD_NUMBER.*/#define BUILD_NUMBER \"$(NEXTVER)\"/" $(VERSION_FILE) + @sed -i "s/#define BUILD_DATE.*/#define BUILD_DATE \"$(BUILDDATE)\"/" $(VERSION_FILE) + +$(OBJDIR)/proto.o: proto.c $(VERSION_FILE) + $(OBJDIR)/%.o: %.c @echo " CC $<" $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $< @@ -127,8 +163,7 @@ size: $(ELF) clean: @echo " CLEAN" - $(RM) $(OBJS) $(DEPS) $(ELF) $(HEX) $(LIST) $(MAP) - @rmdir $(OBJDIR) 2>/dev/null || true + @rm -rf $(OBJDIR) 2>/dev/null || true flash: $(BIN) @@ -143,4 +178,10 @@ dfuboot: $(BIN) @echo " LOAD $(BIN) THROUGH DFU" $(DFUUTIL) -a0 -D $(BIN) -s 0x08000000 -.PHONY: clean flash boot +openocd: + openocd -f openocd.cfg + +dbg: + arm-none-eabi-gdb $(ELF) -ex 'target remote localhost:3333' -ex 'monitor reset halt' + +.PHONY: size clean flash boot dfuboot openocd dbg diff --git a/F3:F303/PL2303/main.c b/F3:F303/PL2303/main.c index 887503d..6f9c39b 100644 --- a/F3:F303/PL2303/main.c +++ b/F3:F303/PL2303/main.c @@ -21,7 +21,7 @@ #include "usart.h" #include "usb.h" -#define USBBUFSZ 127 +#define MAXSTRLEN RBINSZ const char *test = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y\n" "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y\n"; @@ -32,28 +32,8 @@ void sys_tick_handler(void){ ++Tms; } -// usb getline -char *get_USB(){ - static char tmpbuf[USBBUFSZ+1], *curptr = tmpbuf; - static int rest = USBBUFSZ; - uint8_t x = USB_receive(curptr); - if(!x) return NULL; - curptr[x] = 0; - if(curptr[x-1] == '\n'){ - curptr = tmpbuf; - rest = USBBUFSZ; - return tmpbuf; - } - curptr += x; rest -= x; - if(rest <= 0){ // buffer overflow - curptr = tmpbuf; - rest = USBBUFSZ; - USB_send("USB buffer overflow\n"); - } - return NULL; -} - int main(void){ + char inbuff[MAXSTRLEN+1]; int hse = 0; if(StartHSE()){ hse = 1; @@ -85,20 +65,24 @@ int main(void){ const char *ans = parse_cmd(txt); if(ans) usart_send(ans); } - usb_proc(); - if((txt = get_USB())){ - usart_send("Get by USB: "); - usart_send(txt); usart_putchar('\n'); - const char *ans = parse_cmd(txt); - if(ans) USB_send(ans); - } - if(Tlast){ - usart_send("Tlast="); usart_send(u2str(Tlast)); usart_putchar('\n'); - Tlast = 0; + USB_proc(); + int l = USB_receivestr(inbuff, MAXSTRLEN); + if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n"); + else if(l){ + usart_send("Get by USB "); + usart_send(u2str(l)); usart_send(" bytes:"); + usart_send(inbuff); usart_putchar('\n'); + const char *ans = parse_cmd(inbuff); + if(ans) USB_sendstr(ans); } if(starttest){ - --starttest; - USB_send(test); + USB_sendstr(test); + if(0 == --starttest){ +#define SENDBOTH(x) do{char *_ = x; usart_send(_); USB_sendstr(_);}while(0) + SENDBOTH("ENDT="); + SENDBOTH(u2str(Tms)); + usart_putchar('\n'); USB_putbyte('\n'); + } } } } diff --git a/F3:F303/PL2303/pl2303.bin b/F3:F303/PL2303/pl2303.bin index 00fde62..4cb469a 100755 Binary files a/F3:F303/PL2303/pl2303.bin and b/F3:F303/PL2303/pl2303.bin differ diff --git a/F3:F303/PL2303/pl2303.cflags b/F3:F303/PL2303/pl2303.cflags new file mode 100644 index 0000000..68d5165 --- /dev/null +++ b/F3:F303/PL2303/pl2303.cflags @@ -0,0 +1 @@ +-std=c17 \ No newline at end of file diff --git a/F3:F303/PL2303/pl2303.config b/F3:F303/PL2303/pl2303.config new file mode 100644 index 0000000..1cf1964 --- /dev/null +++ b/F3:F303/PL2303/pl2303.config @@ -0,0 +1,7 @@ +// Add predefined macros for your project here. For example: +// #define THE_ANSWER 42 +#define EBUG +#define STM32F3 +#define STM32F303xb +#define __thumb2__ 1 +#define __ARM_ARCH_7M__ diff --git a/F3:F303/PL2303/pl2303.creator b/F3:F303/PL2303/pl2303.creator new file mode 100644 index 0000000..e94cbbd --- /dev/null +++ b/F3:F303/PL2303/pl2303.creator @@ -0,0 +1 @@ +[General] diff --git a/F3:F303/PL2303/pl2303.creator.user b/F3:F303/PL2303/pl2303.creator.user new file mode 100644 index 0000000..aa79e75 --- /dev/null +++ b/F3:F303/PL2303/pl2303.creator.user @@ -0,0 +1,171 @@ + + + + + + EnvironmentId + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + false + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 2 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + 0 + 0 + 0 + + /Big/Data/00__Electronics/STM32/F303-nolib/blink + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Развёртывание + Развёртывание + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/F3:F303/PL2303/pl2303.cxxflags b/F3:F303/PL2303/pl2303.cxxflags new file mode 100644 index 0000000..6435dfc --- /dev/null +++ b/F3:F303/PL2303/pl2303.cxxflags @@ -0,0 +1 @@ +-std=c++17 \ No newline at end of file diff --git a/F3:F303/PL2303/pl2303.files b/F3:F303/PL2303/pl2303.files new file mode 100644 index 0000000..68d42e7 --- /dev/null +++ b/F3:F303/PL2303/pl2303.files @@ -0,0 +1,15 @@ +hardware.c +hardware.h +main.c +proto.c +proto.h +ringbuffer.c +ringbuffer.h +usart.c +usart.h +usb.c +usb.h +usb_lib.c +usb_lib.h +usbhw.c +usbhw.h diff --git a/F3:F303/PL2303/pl2303.includes b/F3:F303/PL2303/pl2303.includes new file mode 100644 index 0000000..06d1130 --- /dev/null +++ b/F3:F303/PL2303/pl2303.includes @@ -0,0 +1,6 @@ +. +../inc +../inc/Fx +../inc/cm +../inc/ld +../inc/startup diff --git a/F3:F303/PL2303/proto.c b/F3:F303/PL2303/proto.c index 7292ab8..e5e930f 100644 --- a/F3:F303/PL2303/proto.c +++ b/F3:F303/PL2303/proto.c @@ -19,6 +19,7 @@ #include "proto.h" #include "usart.h" #include "usb.h" +#include "version.inc" uint8_t starttest = 50; @@ -153,6 +154,7 @@ char *getnum(const char *txt, uint32_t *N){ } const char* helpmsg = + "https://github.com/eddyem/stm32samples/tree/master/F3:F303/PL2303 build#" BUILD_NUMBER " @ " BUILD_DATE "\n" "'i' - print USB->ISTR state\n" "'p' - toggle USB pullup\n" "'N' - read number (dec, 0xhex, 0oct, bbin) and show it in decimal\n" @@ -192,7 +194,7 @@ const char *parse_cmd(const char *buf){ else add2buf("on\n"); break; case 'R': - USB_send("Soft reset\n"); + USB_sendstr("Soft reset\n"); usart_send("Soft reset\n"); NVIC_SystemReset(); break; @@ -208,7 +210,7 @@ const char *parse_cmd(const char *buf){ add2buf("\n"); break; case 'W': - USB_send("Wait for reboot\n"); + USB_sendstr("Wait for reboot\n"); usart_send("Wait for reboot\n"); while(1){nop();}; break; diff --git a/F3:F303/PL2303/ringbuffer.c b/F3:F303/PL2303/ringbuffer.c index 6b292ce..d70a9a7 100644 --- a/F3:F303/PL2303/ringbuffer.c +++ b/F3:F303/PL2303/ringbuffer.c @@ -16,71 +16,109 @@ * along with this program. If not, see . */ -#include -#include - #include "ringbuffer.h" -#include "usb.h" -#include "usb_lib.h" -// ring buffer -static char ringbuffer[RBSIZE]; -// head - position of first data byte -// tail - position of last data byte + 1 -// head == tail - empty! So, buffer can't store more than RBSIZE-1 bytes of data! -static volatile int head = 0, tail = 0; - -static int datalen(){ - if(tail >= head) return (tail - head); - else return (RBSIZE - head + tail); -} -static int restlen(){ - return (RBSIZE - 1 - datalen()); +// stored data length +int RB_datalen(ringbuffer *b){ + if(b->tail >= b->head) return (b->tail - b->head); + else return (b->length - b->head + b->tail); } -TRUE_INLINE void incr(volatile int *what, int n){ +/** + * @brief RB_hasbyte - check if buffer has given byte stored + * @param b - buffer + * @param byte - byte to find + * @return index if found, -1 if none + */ +int RB_hasbyte(ringbuffer *b, uint8_t byte){ + if(b->head == b->tail) return -1; // no data in buffer + int startidx = b->head; + if(b->head > b->tail){ // + for(int found = b->head; found < b->length; ++found) + if(b->data[found] == byte) return found; + startidx = 0; + } + for(int found = startidx; found < b->tail; ++found) + if(b->data[found] == byte) return found; + return -1; +} + +// poor memcpy +static void mcpy(uint8_t *targ, const uint8_t *src, int l){ + while(l--) *targ++ = *src++; +} + +// increment head or tail +TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ *what += n; - if(*what >= RBSIZE) *what -= RBSIZE; + if(*what >= b->length) *what -= b->length; } -int RB_read(char s[BLOCKSIZE]){ - int l = datalen(); +/** + * @brief RB_read - read data from ringbuffer + * @param b - buffer + * @param s - array to write data + * @param len - max len of `s` + * @return bytes read + */ +int RB_read(ringbuffer *b, uint8_t *s, int len){ + int l = RB_datalen(b); if(!l) return 0; - if(l > BLOCKSIZE) l = BLOCKSIZE; - int _1st = RBSIZE - head; + if(l > len) l = len; + int _1st = b->length - b->head; if(_1st > l) _1st = l; - if(_1st > BLOCKSIZE) _1st = BLOCKSIZE; - memcpy(s, ringbuffer+head, _1st); - if(_1st < BLOCKSIZE && l > _1st){ - memcpy(s+_1st, ringbuffer, l-_1st); - incr(&head, l); + if(_1st > len) _1st = len; + mcpy(s, b->data + b->head, _1st); + if(_1st < len && l > _1st){ + mcpy(s+_1st, b->data, l - _1st); + incr(b, &b->head, l); return l; } - incr(&head ,_1st); + incr(b, &b->head, _1st); return _1st; } -static int addportion(const char *str, int l){ - int r = restlen(); +/** + * @brief RB_readto fill array `s` with data until byte `byte` (with it) + * @param b - ringbuffer + * @param byte - check byte + * @param s - buffer to write data + * @param len - length of `s` + * @return amount of bytes written (negative, if lenhead; + // now calculate length of new data portion + if(idx < b->head) partlen += b->length; + if(partlen > len) return -RB_read(b, s, len); + return RB_read(b, s, partlen); +} + +/** + * @brief RB_write - write some data to ringbuffer + * @param b - buffer + * @param str - data + * @param l - length + * @return amount of bytes written + */ +int RB_write(ringbuffer *b, const uint8_t *str, int l){ + int r = b->length - 1 - RB_datalen(b); // rest length if(l > r) l = r; if(!l) return 0; - int _1st = RBSIZE - tail; + int _1st = b->length - b->tail; if(_1st > l) _1st = l; - memcpy(ringbuffer+tail, str, _1st); + mcpy(b->data + b->tail, str, _1st); if(_1st < l){ // add another piece from start - memcpy(ringbuffer, str+_1st, l-_1st); + mcpy(b->data, str+_1st, l-_1st); } - incr(&tail, l); + incr(b, &b->tail, l); return l; } -void RB_write(const char *str, int l){ - if(!str || !*str) return; - if(!usbON) return; - while(l){ - send_next(); - int a = addportion(str, l); - l -= a; - str += a; - } +// just delete all information in buffer `b` +void RB_clearbuf(ringbuffer *b){ + b->head = 0; + b->tail = 0; } diff --git a/F3:F303/PL2303/ringbuffer.h b/F3:F303/PL2303/ringbuffer.h index 3e8f004..df5e3dc 100644 --- a/F3:F303/PL2303/ringbuffer.h +++ b/F3:F303/PL2303/ringbuffer.h @@ -20,14 +20,20 @@ #ifndef RINGBUFFER_H__ #define RINGBUFFER_H__ -#include "usbhw.h" +#include -// ring buffer size in bytes -#define RBSIZE (512) -// max reading portion size -#define BLOCKSIZE (USB_TXBUFSZ) +typedef struct{ + uint8_t *data; // data buffer + const int length; // its length + int head; // head index + int tail; // tail index +} ringbuffer; -int RB_read(char s[BLOCKSIZE]); -void RB_write(const char *str, int l); +int RB_read(ringbuffer *b, uint8_t *s, int len); +int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); +int RB_hasbyte(ringbuffer *b, uint8_t byte); +int RB_write(ringbuffer *b, const uint8_t *str, int l); +int RB_datalen(ringbuffer *b); +void RB_clearbuf(ringbuffer *b); #endif // RINGBUFFER_H__ diff --git a/F3:F303/PL2303/usb.c b/F3:F303/PL2303/usb.c index 3224ddc..68e7f71 100644 --- a/F3:F303/PL2303/usb.c +++ b/F3:F303/PL2303/usb.c @@ -23,32 +23,105 @@ #include "usb.h" #include "usb_lib.h" -static char usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data -static volatile uint8_t tx_succesfull = 1; -static volatile uint8_t rxNE = 0; +static uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data +// ring buffers for incoming and outgoing data +static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ]; +static ringbuffer out = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0}; +static ringbuffer in = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0}; +// transmission is succesfull +static volatile uint8_t bufisempty = 1; +static volatile uint8_t bufovrfl = 0; -volatile uint32_t Tlast = 0; - -void send_next(){ +static void send_next(){ + if(bufisempty) return; static int lastdsz = 0; - if(!tx_succesfull) return; - int buflen = RB_read(usbbuff); + int buflen = RB_read(&out, usbbuff, USB_TXBUFSZ); if(!buflen){ - if(lastdsz) Tlast = Tms; if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz = 0; + bufisempty = 1; return; } - tx_succesfull = 0; - EP_Write(3, (uint8_t*)usbbuff, buflen); + EP_Write(3, usbbuff, buflen); lastdsz = buflen; } +// blocking send full content of ring buffer +int USB_sendall(){ + while(!bufisempty){ + if(!usbON) return 0; + } + return 1; +} + // put `buf` into queue to send -void USB_send(const char *buf){ - int len = strlen(buf); - if(!usbON || !len) return; - RB_write(buf, len); // this is a blocking procedure if there's too little free memory in buffer +int USB_send(const uint8_t *buf, int len){ + if(!buf || !usbON || !len) return 0; + while(len){ + int a = RB_write(&out, buf, len); + len -= a; + buf += a; + if(bufisempty){ + bufisempty = 0; + send_next(); + } + } + return 1; +} + +int USB_putbyte(uint8_t byte){ + if(!usbON) return 0; + while(0 == RB_write(&out, &byte, 1)){ + if(bufisempty){ + bufisempty = 0; + send_next(); + } + } + return 1; +} + +int USB_sendstr(const char *string){ + if(!string || !usbON) return 0; + int len = 0; + const char *b = string; + while(*b++) ++len; + if(!len) return 0; + return USB_send((const uint8_t*)string, len); +} + +/** + * @brief USB_receive - get binary data from receiving ring-buffer + * @param buf (i) - buffer for received data + * @param len - length of `buf` + * @return amount of received bytes (negative, if overfull happened) + */ +int USB_receive(uint8_t *buf, int len){ + int sz = RB_read(&in, buf, len); + if(bufovrfl){ + RB_clearbuf(&in); + if(!sz) sz = -1; + else sz = -sz; + bufovrfl = 0; + } + return sz; +} + +/** + * @brief USB_receivestr - get string up to '\n' and replace '\n' with 0 + * @param buf - receiving buffer + * @param len - its length + * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) + */ +int USB_receivestr(char *buf, int len){ + int l = RB_readto(&in, '\n', (uint8_t*)buf, len); + if(l < 0 || bufovrfl) RB_clearbuf(&in); + else buf[l] = 0; // replace '\n' with strend + if(bufovrfl){ + if(l > 0) l = -l; + else l = -1; + bufovrfl = 0; + } + return l; } // interrupt IN handler (never used?) @@ -63,7 +136,6 @@ static void EP1_Handler(){ // data IN/OUT handlers static void transmit_Handler(){ // EP3IN - tx_succesfull = 1; uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]); // clear CTR keep DTOGs & STATs USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr @@ -71,12 +143,17 @@ static void transmit_Handler(){ // EP3IN } static void receive_Handler(){ // EP2OUT - rxNE = 1; - uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[2]); - USB->EPnR[2] = (epstatus & ~(USB_EPnR_CTR_RX)); // clear RX ctr + uint8_t buf[USB_RXBUFSZ]; + uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); + uint8_t sz = EP_Read(2, (uint16_t*)buf); + if(sz){ + if(RB_write(&in, buf, sz) != sz) bufovrfl = 1; + } + // keep stat_tx & set ACK rx, clear RX ctr + USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX; } -void usb_proc(){ +void USB_proc(){ switch(USB_Dev.USB_Status){ case USB_STATE_CONFIGURED: // make new BULK endpoint @@ -94,21 +171,5 @@ void usb_proc(){ break; default: // USB_STATE_CONNECTED - send next data portion if(!usbON) return; - send_next(); } } - -/** - * @brief USB_receive - * @param buf (i) - buffer[64] for received data - * @return amount of received bytes - */ -int USB_receive(char *buf){ - if(!usbON || !rxNE) return 0; - int sz = EP_Read(2, (uint16_t*)buf); - uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); - // keep stat_tx & set ACK rx - USB->EPnR[2] = (epstatus & ~(USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX; - rxNE = 0; - return sz; -} diff --git a/F3:F303/PL2303/usb.h b/F3:F303/PL2303/usb.h index cc697b7..15d1172 100644 --- a/F3:F303/PL2303/usb.h +++ b/F3:F303/PL2303/usb.h @@ -22,13 +22,17 @@ #include "usbhw.h" -#define BUFFSIZE (64) +// sizes of ringbuffers for outgoing and incoming data +#define RBOUTSZ (512) +#define RBINSZ (512) -extern volatile uint32_t Tlast; +void USB_proc(); +int USB_sendall(); +int USB_send(const uint8_t *buf, int len); +int USB_putbyte(uint8_t byte); +int USB_sendstr(const char *string); +int USB_receive(uint8_t *buf, int len); +int USB_receivestr(char *buf, int len); -void usb_proc(); -void send_next(); -void USB_send(const char *buf); -int USB_receive(char *buf); #endif // __USB_H__ diff --git a/F3:F303/PL2303/version.inc b/F3:F303/PL2303/version.inc new file mode 100644 index 0000000..44a91c7 --- /dev/null +++ b/F3:F303/PL2303/version.inc @@ -0,0 +1,2 @@ +#define BUILD_NUMBER "14" +#define BUILD_DATE "2023-01-18" diff --git a/F3:F303/floatPrintf/Makefile b/F3:F303/floatPrintf/Makefile index 0e78c99..bc5af43 100644 --- a/F3:F303/floatPrintf/Makefile +++ b/F3:F303/floatPrintf/Makefile @@ -10,8 +10,6 @@ ARMARCH = __ARM_ARCH_7M__ # change this linking script depending on particular MCU model, LDSCRIPT ?= stm32f303xB.ld -INDEPENDENT_HEADERS= - FP_FLAGS ?= -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -mlittle-endian -DARM_MATH_CM4 ASM_FLAGS ?= -mthumb -mcpu=cortex-m4 ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS) -D $(ARMARCH) @@ -42,6 +40,8 @@ DFUUTIL := $(shell which dfu-util) OBJDIR := mk # target (debug/release) TARGFILE := $(OBJDIR)/TARGET +# autoincremental version & build date +VERSION_FILE = version.inc SRC := $(wildcard *.c) OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) STARTUP := $(OBJDIR)/startup.o @@ -94,6 +94,13 @@ ifeq ($(TARGET), DEBUG) .DEFAULT_GOAL := debug endif +ifeq ($(shell test -e $(VERSION_FILE) && echo -n yes), yes) + NEXTVER := $(shell expr $$(awk '/#define BUILD_NUMBER/' $(VERSION_FILE) | tr -cd "[0-9]") + 1) +else + NEXTVER := "1" +endif +BUILDDATE := $(shell date +%Y-%m-%d) + # release: add LTO release: CFLAGS += -flto release: LDFLAGS += -flto @@ -123,6 +130,14 @@ $(OBJDIR): $(STARTUP): $(INC_DIR)/startup/vector.c $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $< +$(VERSION_FILE): *.[ch] + @[ -f $(VERSION_FILE) ] || echo -e "#define BUILD_NUMBER \"0\"\n#define BUILD_DATE \"none\"" > $(VERSION_FILE) + @echo " Generate version: $(NEXTVER) for date $(BUILDDATE)" + @sed -i "s/#define BUILD_NUMBER.*/#define BUILD_NUMBER \"$(NEXTVER)\"/" $(VERSION_FILE) + @sed -i "s/#define BUILD_DATE.*/#define BUILD_DATE \"$(BUILDDATE)\"/" $(VERSION_FILE) + +#$(OBJDIR)/proto.o: proto.c $(VERSION_FILE) + $(OBJDIR)/%.o: %.c @echo " CC $<" $(CC) $(CFLAGS) $(DEFS) $(INCLUDE) -o $@ -c $< diff --git a/F3:F303/floatPrintf/float.bin b/F3:F303/floatPrintf/float.bin index bb8f6cc..69e092b 100755 Binary files a/F3:F303/floatPrintf/float.bin and b/F3:F303/floatPrintf/float.bin differ diff --git a/F3:F303/floatPrintf/main.c b/F3:F303/floatPrintf/main.c index 6c51198..683d6dc 100644 --- a/F3:F303/floatPrintf/main.c +++ b/F3:F303/floatPrintf/main.c @@ -101,7 +101,7 @@ NAN, INFINITY, -INFINITY}; #define TESTN 12 int main(void){ - sysreset(); +// sysreset(); if(!StartHSE()) StartHSI(); SysTick_Config((uint32_t)72000); // 1ms hw_setup(); diff --git a/F3:F303/inc/Fx/stm32f3.h b/F3:F303/inc/Fx/stm32f3.h index b2a6e69..e6b1b15 100644 --- a/F3:F303/inc/Fx/stm32f3.h +++ b/F3:F303/inc/Fx/stm32f3.h @@ -32,15 +32,7 @@ #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ -/* -TRUE_INLINE void enable_FPU(){ - SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); // set CP10 and CP11 Full Access -}*/ - -//extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ -//extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ -//extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ - +#if 0 /** * @brief Setup the microcontroller system * Initialize the FPU setting, vector table location and the PLL configuration is reset. @@ -80,52 +72,57 @@ TRUE_INLINE void sysreset(void) // not usable SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } +#endif -TRUE_INLINE void StartHSI(){ // system bus 48MHz from PLL, USBPPRE=1 +#define WAITWHILE(x) do{StartUpCounter = 0; while((x) && (++StartUpCounter < 3600000)){nop();}}while(0) +TRUE_INLINE void StartHSI(){ // system bus 48MHz from PLL __IO uint32_t StartUpCounter = 0; -#define WAITWHILE(x) do{StartUpCounter = 0; while((x) && (++StartUpCounter < 0xffffff)){nop();}}while(0) - RCC->CR = (RCC->CR & ~RCC_CR_PLLON) | RCC_CR_HSION; + RCC->CR |= RCC_CR_HSION; // To adjust HSI set value of HSITRIM here WAITWHILE(!(RCC->CR & RCC_CR_HSIRDY)); + RCC->CFGR &= ~RCC_CFGR_SW; // set sysclock to HSI + WAITWHILE(RCC->CFGR & RCC_CFGR_SWS); + RCC->CR &= ~(RCC_CR_PLLON | RCC_CR_HSEON); + WAITWHILE(RCC->CR & RCC_CR_PLLRDY); // wait while PLL will be off FLASH->ACR = (FLASH->ACR & ~(FLASH_ACR_LATENCY)) | - FLASH_ACR_LATENCY_0 | FLASH_ACR_PRFTBE; - RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 | - RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL | RCC_CFGR_USBPRE) - ) | RCC_CFGR_PLLSRC_HSI_DIV2 | RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE_DIV1; + FLASH_ACR_LATENCY_1 | FLASH_ACR_PRFTBE; + RCC->CFGR = RCC_CFGR_PLLSRC_HSI_DIV2 | RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE_DIV1 | RCC_CFGR_PPRE1_DIV2; RCC->CR |= RCC_CR_PLLON; // Enable PLL // Wait till PLL is ready WAITWHILE(!(RCC->CR & RCC_CR_PLLRDY)); // Select PLL as system clock source RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; // Wait till PLL is used as system clock source - WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); -#undef WAITWHILE + WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); + SysFreq = 48000000; } // @return 1 if OK, 0 if failed TRUE_INLINE int StartHSE(){ // system bus 72MHz from PLL __IO uint32_t StartUpCounter = 0; -#define WAITWHILE(x) do{StartUpCounter = 0; while((x) && (++StartUpCounter < 0xffffff)){nop();}; if(x) return 0;}while(0) - RCC->CR = (RCC->CR & ~RCC_CR_PLLON) | RCC_CR_HSEON; // disable PLL to reconfigure, enable HSE + RCC->CFGR &= ~RCC_CFGR_SW; // set sysclock to HSI + WAITWHILE(RCC->CFGR & RCC_CFGR_SWS); + RCC->CR &= ~RCC_CR_PLLON; + WAITWHILE(RCC->CR & RCC_CR_PLLRDY); // wait while PLL will be off + RCC->CR |= RCC_CR_HSEON; // disable PLL to reconfigure, enable HSE WAITWHILE(!(RCC->CR & RCC_CR_HSERDY)); // Enable Prefetch Buffer. Flash 4 wait states for 48..72MHz FLASH->ACR = (FLASH->ACR & ~(FLASH_ACR_LATENCY)) | FLASH_ACR_LATENCY_2 | FLASH_ACR_PRFTBE; - // HCLK = SYSCLK (AHB prescaler = 1), PCLK1 = HCLK (APB1 prescaler = 1), PCLK2 = HCLK (APB2 prescaler = 1) - // PLLCLK = HSE * 9 = 72MHz - RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 | - RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL | RCC_CFGR_USBPRE) - ) | RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLMUL9 | RCC_CFGR_USBPRE_DIV1_5; + // HCLK = SYSCLK (AHB prescaler = 1), PCLK1 = HCLK/2 (APB1 prescaler = 2, max freq = 36MHz), + // PCLK2 = HCLK (APB2 prescaler = 1), PLLCLK = HSE * 9 = 72MHz + RCC->CFGR = RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLMUL9 | RCC_CFGR_PPRE1_DIV2; RCC->CR |= RCC_CR_PLLON; // Enable PLL // Wait till PLL is ready WAITWHILE(!(RCC->CR & RCC_CR_PLLRDY)); // Select PLL as system clock source RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; // Wait till PLL is used as system clock source - WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); -#undef WAITWHILE + WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); + SysFreq = 72000000; return 1; } +#undef WAITWHILE /******************* Bit definition for GPIO_MODER register *****************/ // _AI - analog inpt, _O - general output, _AF - alternate function @@ -251,6 +248,20 @@ TRUE_INLINE int StartHSE(){ // system bus 72MHz from PLL #define GPIO_OSPEEDR15_MED ((uint32_t)(1<<30)) #define GPIO_OSPEEDR15_HIGH ((uint32_t)(3<<30)) +// clear MODER: ~GPIO_MODER_MODERXX_Msk, you should AND these +#define MODER_CLR(n) (~(3<<(n*2))) +// _AI - analog inpt, _O - general output, _AF - alternate function +// these should be OR'ed +#define MODER_I(n) (0) +#define MODER_O(n) (1<<(n*2)) +#define MODER_AF(n) (2<<(n*2)) +#define MODER_AI(n) (3<<(n*2)) + +// AFR field: afr - AFR number, pin - pin (0..15) +TRUE_INLINE uint32_t AFRf(uint8_t afr, uint8_t pin){ + if(pin > 7) pin -= 8; + return (afr << (pin * 4)); +} /************************* ADC *************************/ /* inner termometer calibration values diff --git a/F3:F303/inc/Fx/vector.h b/F3:F303/inc/Fx/vector.h index 1ab96f1..78fdc52 100644 --- a/F3:F303/inc/Fx/vector.h +++ b/F3:F303/inc/Fx/vector.h @@ -25,6 +25,8 @@ #ifndef WEAK #define WEAK __attribute__((weak)) #endif +#include +extern uint32_t SysFreq; void WEAK reset_handler(void); void WEAK nmi_handler(void); diff --git a/F3:F303/inc/startup/vector.c b/F3:F303/inc/startup/vector.c index 6a908a8..b566483 100644 --- a/F3:F303/inc/startup/vector.c +++ b/F3:F303/inc/startup/vector.c @@ -19,6 +19,8 @@ */ #include "vector.h" +uint32_t SysFreq = 0; + typedef void (*vector_table_entry_t)(void); typedef void (*funcp_t) (void);