diff options
-rw-r--r-- | CMakeLists.txt | 33 | ||||
-rw-r--r-- | debug.cpp | 2 | ||||
-rw-r--r-- | serial1.cpp | 3 | ||||
-rw-r--r-- | serial2.cpp | 131 | ||||
-rw-r--r-- | test1.cpp | 2 | ||||
-rwxr-xr-x | tmp/printf/printf.c | 245 | ||||
-rwxr-xr-x | tmp/printf/printf.h | 129 |
7 files changed, 164 insertions, 381 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e1d5438..c894168 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,12 +19,16 @@ function(add_extra_commands target_name) COMMAND arm-none-eabi-objcopy -O binary ${target_name} ${target_name}.bin) endfunction() +# https://github.com/cjlano/tinyprintf +add_library(tinyprintf STATIC tinyprintf/tinyprintf.c tinyprintf/tinyprintf.h) +target_include_directories(tinyprintf PUBLIC tinyprintf) + ######################################################################################################### # test1 add_executable(test1.elf test1.cpp init_low.s init_high.cpp include/stm32f10x_conf.h # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php - tmp/printf/printf.h tmp/printf/printf.c + tinyprintf/tinyprintf.c tinyprintf/tinyprintf.h tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c @@ -33,6 +37,7 @@ add_executable(test1.elf test1.cpp init_low.s init_high.cpp include/stm32f10x_co target_include_directories(test1.elf PUBLIC include + tinyprintf tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc) @@ -48,7 +53,7 @@ add_extra_commands(test1.elf) add_executable(serial1.elf serial1.cpp init_low.s init_high.cpp include/stm32f10x_conf.h debug.cpp debug.h # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php - tmp/printf/printf.h tmp/printf/printf.c + tinyprintf/tinyprintf.c tinyprintf/tinyprintf.h tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c @@ -57,7 +62,7 @@ add_executable(serial1.elf serial1.cpp init_low.s init_high.cpp include/stm32f10 target_include_directories(serial1.elf PUBLIC include - tmp/printf + tinyprintf tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc) @@ -65,3 +70,25 @@ target_compile_definitions(serial1.elf PUBLIC STM32F10X_MD USE_STDPERIPH_DRIVER) set_target_properties(serial1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") add_extra_commands(serial1.elf) + +######################################################################################################### +# serial2 + +add_executable(serial2.elf serial2.cpp init_low.s init_high.cpp include/stm32f10x_conf.h + debug.cpp debug.h + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) +target_link_libraries(serial2.elf tinyprintf) + +target_include_directories(serial2.elf PUBLIC + include + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(serial2.elf PUBLIC STM32F10X_MD USE_STDPERIPH_DRIVER) + +set_target_properties(serial2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(serial2.elf) @@ -1,5 +1,5 @@ #include "debug.h" -#include "printf.h" +#include "tinyprintf.h" #ifdef __cplusplus extern "C" { diff --git a/serial1.cpp b/serial1.cpp index 6bafb5a..58ea536 100644 --- a/serial1.cpp +++ b/serial1.cpp @@ -1,10 +1,11 @@ +#include "tinyprintf.h" #include <stdint.h> #include <stm32f10x.h> #include <stm32f10x_rcc.h> #include <stm32f10x_gpio.h> #include <stddef.h> #include <stdarg.h> -#include "printf.h" +#include "tinyprintf.h" #include "debug.h" int init_high(); diff --git a/serial2.cpp b/serial2.cpp new file mode 100644 index 0000000..58ea536 --- /dev/null +++ b/serial2.cpp @@ -0,0 +1,131 @@ +#include "tinyprintf.h" +#include <stdint.h> +#include <stm32f10x.h> +#include <stm32f10x_rcc.h> +#include <stm32f10x_gpio.h> +#include <stddef.h> +#include <stdarg.h> +#include "tinyprintf.h" +#include "debug.h" + +int init_high(); + +extern "C" void halt(); + +#include "stm32f10x_conf.h" + +extern "C" +__attribute__((naked)) +void HardFault_Handler_C(uint32_t *hardfault_args) { + halt(); +} + +size_t strlen(const char *s) { + size_t size = 0; + while (*s++ != '\0') size++; + return size; +} + +int run = 1; + +volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE; + +/* + * When we get there the stack pointer is set + */ +int main() { + SystemInit(); + + init_printf(nullptr, dbg_putc); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO + | RCC_APB2Periph_USART1 + | RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_GPIOC, + ENABLE); + + /* ***************************************** */ + + // Debug on port B + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + // Make Port B's pin #5 the debug output pin + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_5; + init.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &init); + + /* ***************************************** */ + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); + + /* + * PA9 USART1_TX + * PA10 USART1_RX + */ + + // Enable USART1 + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + + // Make the TX pin an output + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_9; + init.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &init); + + // 8 bit mode + USART1->CR1 &= ~USART_CR1_M; + USART1->CR2 &= ~USART_CR2_STOP_1; + + USART1->CR1 |= USART_CR1_UE /* Set UART Enable */ + | USART_CR1_TE; /* Set Transmission Enable */ + + // Set baud rate + int mantissa = 39; + int fraction = static_cast<int>(16 * 0.0625); // == 1 + // 72M / (16*39.0625) = 115200 + USART1->BRR = static_cast<uint16_t >(mantissa << 4 | fraction); + + char c = 'A'; + while (run) { + int txe = USART1->SR & USART_SR_TXE; + +// dbg_printf("1:%d?\n", x); + +// char mm[100]; +// tfp_sprintf(mm, "2:%d?\n", x); +// send_command(SYS_WRITE0, mm); + +// printf(" %u?\n", usart1->SR); +// printf(" %u?\n", 1); + + if (txe) { + GPIO_SetBits(GPIOB, GPIO_Pin_All); + GPIO_ResetBits(GPIOB, GPIO_Pin_All); + + USART1->DR = (uint16_t) c; +// USART1->DR = 0x55; + + if (c == 'Z') { + c = 'a'; + } else if (c == 'z') { + c = '0'; + } else if (c == '9') { + c = '\n'; + } else if (c == '\n') { + c = 'A'; + } else { + c++; + } + } + } + + return 0; +} + @@ -9,8 +9,6 @@ int init_high(); extern "C" void halt(); -#include "tmp/printf/printf.h" - #include "stm32f10x_conf.h" extern "C" diff --git a/tmp/printf/printf.c b/tmp/printf/printf.c deleted file mode 100755 index f10f61f..0000000 --- a/tmp/printf/printf.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its - * contributors may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include "printf.h" - -typedef void (*putcf) (void*,char); -static putcf stdout_putf; -static void* stdout_putp; - - -#ifdef PRINTF_LONG_SUPPORT - -static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) - { - int n=0; - unsigned int d=1; - while (num/d >= base) - d*=base; - while (d!=0) { - int dgt = num / d; - num%=d; - d/=base; - if (n || dgt>0|| d==0) { - *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); - ++n; - } - } - *bf=0; - } - -static void li2a (long num, char * bf) - { - if (num<0) { - num=-num; - *bf++ = '-'; - } - uli2a(num,10,0,bf); - } - -#endif - -static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) - { - int n=0; - unsigned int d=1; - while (num/d >= base) - d*=base; - while (d!=0) { - int dgt = num / d; - num%= d; - d/=base; - if (n || dgt>0 || d==0) { - *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); - ++n; - } - } - *bf=0; - } - -static void i2a (int num, char * bf) - { - if (num<0) { - num=-num; - *bf++ = '-'; - } - ui2a(num,10,0,bf); - } - -static int a2d(char ch) - { - if (ch>='0' && ch<='9') - return ch-'0'; - else if (ch>='a' && ch<='f') - return ch-'a'+10; - else if (ch>='A' && ch<='F') - return ch-'A'+10; - else return -1; - } - -static char a2i(char ch, const char** src,int base,int* nump) - { - const char* p= *src; - int num=0; - int digit; - while ((digit=a2d(ch))>=0) { - if (digit>base) break; - num=num*base+digit; - ch=*p++; - } - *src=p; - *nump=num; - return ch; - } - -static void putchw(void* putp,putcf putf,int n, char z, char* bf) - { - char fc=z? '0' : ' '; - char ch; - char* p=bf; - while (*p++ && n > 0) - n--; - while (n-- > 0) - putf(putp,fc); - while ((ch= *bf++)) - putf(putp,ch); - } - -void tfp_format(void* putp,putcf putf,const char *fmt, va_list va) - { - char bf[12]; - - char ch; - - - while ((ch=*(fmt++))) { - if (ch!='%') - putf(putp,ch); - else { - char lz=0; -#ifdef PRINTF_LONG_SUPPORT - char lng=0; -#endif - int w=0; - ch=*(fmt++); - if (ch=='0') { - ch=*(fmt++); - lz=1; - } - if (ch>='0' && ch<='9') { - ch=a2i(ch,&fmt,10,&w); - } -#ifdef PRINTF_LONG_SUPPORT - if (ch=='l') { - ch=*(fmt++); - lng=1; - } -#endif - switch (ch) { - case 0: - goto abort; - case 'u' : { -#ifdef PRINTF_LONG_SUPPORT - if (lng) - uli2a(va_arg(va, unsigned long int),10,0,bf); - else -#endif - ui2a(va_arg(va, unsigned int),10,0,bf); - putchw(putp,putf,w,lz,bf); - break; - } - case 'd' : { -#ifdef PRINTF_LONG_SUPPORT - if (lng) - li2a(va_arg(va, unsigned long int),bf); - else -#endif - i2a(va_arg(va, int),bf); - putchw(putp,putf,w,lz,bf); - break; - } - case 'x': case 'X' : -#ifdef PRINTF_LONG_SUPPORT - if (lng) - uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); - else -#endif - ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); - putchw(putp,putf,w,lz,bf); - break; - case 'c' : - putf(putp,(char)(va_arg(va, int))); - break; - case 's' : - putchw(putp,putf,w,0,va_arg(va, char*)); - break; - case '%' : - putf(putp,ch); - default: - break; - } - } - } - abort:; - } - - -void init_printf(void* putp,void (*putf) (void*,char)) - { - stdout_putf=putf; - stdout_putp=putp; - } - -void tfp_printf(const char *fmt, ...) - { - va_list va; - va_start(va,fmt); - tfp_format(stdout_putp,stdout_putf,fmt,va); - va_end(va); - } - -static void putcp(void* p,char c) - { - *(*((char**)p))++ = c; - } - - - -void tfp_sprintf(char* s,const char *fmt, ...) - { - va_list va; - va_start(va,fmt); - tfp_format(&s,putcp,fmt,va); - putcp(&s,0); - va_end(va); - } - - diff --git a/tmp/printf/printf.h b/tmp/printf/printf.h deleted file mode 100755 index 01ea7b9..0000000 --- a/tmp/printf/printf.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -File: printf.h - -Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its -contributors may be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. - ----------------------------------------------------------------------- - -This library is realy just two files: 'printf.h' and 'printf.c'. - -They provide a simple and small (+200 loc) printf functionality to -be used in embedded systems. - -I've found them so usefull in debugging that I do not bother with a -debugger at all. - -They are distributed in source form, so to use them, just compile them -into your project. - -Two printf variants are provided: printf and sprintf. - -The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. - -Zero padding and field width are also supported. - -If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the -long specifier is also -supported. Note that this will pull in some long math routines (pun intended!) -and thus make your executable noticably longer. - -The memory foot print of course depends on the target cpu, compiler and -compiler options, but a rough guestimate (based on a H8S target) is about -1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. -Not too bad. Your milage may vary. By hacking the source code you can -get rid of some hunred bytes, I'm sure, but personally I feel the balance of -functionality and flexibility versus code size is close to optimal for -many embedded systems. - -To use the printf you need to supply your own character output function, -something like : - -void putc ( void* p, char c) - { - while (!SERIAL_PORT_EMPTY) ; - SERIAL_PORT_TX_REGISTER = c; - } - -Before you can call printf you need to initialize it to use your -character output function with something like: - -init_printf(NULL,putc); - -Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', -the NULL (or any pointer) you pass into the 'init_printf' will eventually be -passed to your 'putc' routine. This allows you to pass some storage space (or -anything realy) to the character output function, if necessary. -This is not often needed but it was implemented like that because it made -implementing the sprintf function so neat (look at the source code). - -The code is re-entrant, except for the 'init_printf' function, so it -is safe to call it from interupts too, although this may result in mixed output. -If you rely on re-entrancy, take care that your 'putc' function is re-entrant! - -The printf and sprintf functions are actually macros that translate to -'tfp_printf' and 'tfp_sprintf'. This makes it possible -to use them along with 'stdio.h' printf's in a single source file. -You just need to undef the names before you include the 'stdio.h'. -Note that these are not function like macros, so if you have variables -or struct members with these names, things will explode in your face. -Without variadic macros this is the best we can do to wrap these -fucnction. If it is a problem just give up the macros and use the -functions directly or rename them. - -For further details see source code. - -regs Kusti, 23.10.2004 -*/ - - -#ifndef __TFP_PRINTF__ -#define __TFP_PRINTF__ - -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void init_printf(void* putp,void (*putf) (void*,char)); - -void tfp_printf(const char *fmt, ...); -void tfp_sprintf(char* s,const char *fmt, ...); - -void tfp_format(void* putp,void (*putf) (void*,char),const char *fmt, va_list va); - -#define printf tfp_printf -#define sprintf tfp_sprintf - -#ifdef __cplusplus -}; -#endif - -#endif |