From: Robin Krens Date: Mon, 5 Aug 2019 14:29:35 +0000 (+0800) Subject: basic implemtation general purpose clock and tinyprintf X-Git-Url: https://robinkrens.nl/gitweb/?a=commitdiff_plain;h=dcb2e2b5744f20cbfc979e1f6291ae9937a8affd;p=cortex-from-scratch basic implemtation general purpose clock and tinyprintf TIM4 used as general purpose timer; output mode; sends out continous pulses over GPIOB6. Implementation tinyprintf library (not all converted yet). --- diff --git a/Makefile b/Makefile index 5cc5791..65c1294 100644 --- a/Makefile +++ b/Makefile @@ -24,11 +24,11 @@ _OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o rtc.o OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ)) DDIR = obj/drivers -_DRIVERS = uart.o tm1637.o led.o +_DRIVERS = uart.o tm1637.o led.o tsensor.o DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS)) LDIR = obj/lib -_LIBS = string.o stdio.o regfunc.o pool.o +_LIBS = string.o stdio.o regfunc.o pool.o tinyprintf.o LIBS = $(patsubst %, $(LDIR)/%,$(_LIBS)) $(DDIR)/%.o: drivers/%.c diff --git a/drivers/led.c b/drivers/led.c index 0cdda5a..84c4d0a 100644 --- a/drivers/led.c +++ b/drivers/led.c @@ -31,17 +31,25 @@ void led_init() { - regw_u8(RCC_APB2ENR, 0x1, 4, SETBIT); // enable GPIOC - regw_u32(GPIOC_CRL, 0x44444442, 0, OWRITE); // set PC0 pin to output mode - *GPIOC_ODR = 0xFFFF; // only writable in word mode + rsetbit(RCC_APB2ENR, 5); // enable GPIOD + rsetbit(RCC_APB2ENR, 2); // enable GPIOA + + //rwrite(GPIOD_CRL, 0x44444644); + rsetbitsfrom(GPIOD_CRL, 8, 0x6); + rsetbitsfrom(GPIOA_CRH, 0, 0x6); + rsetbit(GPIOD_ODR, 2); + rclrbit(GPIOA_ODR, 8); } void led_on() { - *GPIOC_ODR = 0x0001; + rsetbit(GPIOD_ODR, 2); + rclrbit(GPIOA_ODR, 8); + } void led_off() { - *GPIOC_ODR = 0x0000; + rclrbit(GPIOD_ODR, 2); + rsetbit(GPIOA_ODR, 8); } diff --git a/drivers/tsensor.c b/drivers/tsensor.c new file mode 100644 index 0000000..499fa45 --- /dev/null +++ b/drivers/tsensor.c @@ -0,0 +1,67 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/8/4 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Temperature sensor + * + * */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +/* void * update_handler() { + + printf("HERE!"); + rclrbit(TIM4_SR1, 0); +} */ + +void tsensor_init( ) { + + int prescaler = 31; + + rsetbit(RCC_APB2ENR, 3); // GPIOB enable + rsetbit(RCC_APB1ENR, 2); // TIM4 enable + rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode + rclrbit(TIM4_CR1, 4); // upcounter (clrbit!) + + rwrite(TIM4_PSC, 0xFFFF); // 1 MHz: 23 + rwrite(TIM4_ARR, 0xAB9); // preload register + + rwrite(GPIOB_CRL, 0x4A444444); // PB6 for Channel 1 TIM4 alternate + + rwrite(TIM4_CCR1, 0x55C); // half of ARR + rwrite(TIM4_RCR, 0x0F); // repeat + rsetbit(TIM4_EGR, 0); // update generation + + rsetbitsfrom(TIM4_CCMR1, 4, 0x7); // PWM mode 1 + + //rsetbit(TIM4_CCMR1, 3); // preload enable + //rsetbit(TIM4_CR1, 7); // buffered + + //rsetbit(TIM4_CR1, 3); // one pulse mode + + rsetbit(TIM4_CCER, 0); // enable output channel 1 +// rsetbit(TIM4_BDTR, 15); // main output + rsetbit(TIM4_CR1, 0); + + /* INTERRUPTS */ + //ivt_set_gate(41, update_handler, 0); + + //rsetbit(TIM4_DIER, 0); + //rsetbit(NVIC_ISER0, 25); // interupt 41 - 32 +} + + diff --git a/drivers/uart.c b/drivers/uart.c index 05f0406..0090ef2 100644 --- a/drivers/uart.c +++ b/drivers/uart.c @@ -38,28 +38,27 @@ void uart_init() { linefeed.wpos = 0; //memset(&linefeed, 0, (sizeof(struct linefeed) )); - //regw_u32(RCC_APB2ENR, 0x4005, 0, SETBIT);// enable clock to UART1, AFIO and GPIOA - rsetbitsfrom(RCC_APB2ENR, 0, 0x4005); + //rsetbitsfrom(RCC_APB2ENR, 0, 0x4005); + rsetbit(RCC_APB2ENR, 0); + rsetbit(RCC_APB2ENR, 2); + rsetbit(RCC_APB2ENR, 14); /* (after enable GPIOA), on PA9&PA10 and set mode * to alternative output */ - //regw_u32(GPIOA_CRH, 0x444444D4, 0, OWRITE); rwrite(GPIOA_CRH, 0x444444D4); - //regw_u8(AFIO_EVCR, 0x89, 0, OWRITE);// set event control register, output on PA, Pin 9 TODO: check + // set event control register, output on PA, Pin 9 TODO: check rsetbitsfrom(AFIO_EVCR, 0, 0x89); //disable temporarily to set values - //regw_u8(USART1_CR1, 0x0, 13, SETBIT); rclrbit(USART1_CR1, 13); set_baudrate(); - //regw_u32(USART1_CR2, 0x0000, 0, OWRITE); //set stop bit, default is 1 stop bit 0x00 + //set stop bit, default is 1 stop bit 0x00 rwrite(USART1_CR2, 0x0000); /* parity = 8 bit, UART1 enabled, * TX and RX enabled, interrupts enabled */ - //regw_u32(USART1_CR1, 0x0000302C, 0, OWRITE); rwrite(USART1_CR1, 0x0000302C); ivt_set_gate(53, uart_handler, 0); diff --git a/include/drivers/tsensor.h b/include/drivers/tsensor.h new file mode 100644 index 0000000..64a5e94 --- /dev/null +++ b/include/drivers/tsensor.h @@ -0,0 +1,2 @@ +extern void tsensor_init(); + diff --git a/include/lib/stdio.h b/include/lib/stdio.h index cf3075b..93d1f99 100644 --- a/include/lib/stdio.h +++ b/include/lib/stdio.h @@ -6,3 +6,4 @@ extern char getchar(); extern void cputchar(char); extern void cputs(unsigned char *); extern char * readline(); +extern void putc(void *, char); diff --git a/include/lib/tinyprintf.h b/include/lib/tinyprintf.h new file mode 100644 index 0000000..8855710 --- /dev/null +++ b/include/lib/tinyprintf.h @@ -0,0 +1,107 @@ +/* +File: tinyprintf.h + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +/* Global configuration */ + +/* Set this to 0 if you do not want to provide tfp_printf */ +#ifndef TINYPRINTF_DEFINE_TFP_PRINTF +# define TINYPRINTF_DEFINE_TFP_PRINTF 1 +#endif + +/* Set this to 0 if you do not want to provide + tfp_sprintf/snprintf/vsprintf/vsnprintf */ +#ifndef TINYPRINTF_DEFINE_TFP_SPRINTF +# define TINYPRINTF_DEFINE_TFP_SPRINTF 1 +#endif + +/* Set this to 0 if you do not want tfp_printf and + tfp_{vsn,sn,vs,s}printf to be also available as + printf/{vsn,sn,vs,s}printf */ +#ifndef TINYPRINTF_OVERRIDE_LIBC +# define TINYPRINTF_OVERRIDE_LIBC 1 +#endif + +/* Optional external types dependencies */ + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +# include /* size_t */ +#endif + +/* Declarations */ + +#ifdef __GNUC__ +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) \ + __attribute__((format (printf, fmt_idx, arg1_idx))) +#else +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*putcf) (void *, char); + +/* + 'tfp_format' really is the central function for all tinyprintf. For + each output character after formatting, the 'putf' callback is + called with 2 args: + - an arbitrary void* 'putp' param defined by the user and + passed unmodified from 'tfp_format', + - the character. + The 'tfp_printf' and 'tfp_sprintf' functions simply define their own + callback and pass to it the right 'putp' it is expecting. +*/ +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va); + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); +int tfp_snprintf(char *str, size_t size, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(3, 4); +int tfp_vsprintf(char *str, const char *fmt, va_list ap); +int tfp_sprintf(char *str, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(2, 3); +# if TINYPRINTF_OVERRIDE_LIBC +# define vsnprintf tfp_vsnprintf +# define snprintf tfp_snprintf +# define vsprintf tfp_vsprintf +# define sprintf tfp_sprintf +# endif +#endif + +#if TINYPRINTF_DEFINE_TFP_PRINTF +void init_printf(void *putp, putcf putf); +void tfp_printf(char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2); +# if TINYPRINTF_OVERRIDE_LIBC +# define printf tfp_printf +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sys/mmap.h b/include/sys/mmap.h index 6dda221..ee0da1e 100644 --- a/include/sys/mmap.h +++ b/include/sys/mmap.h @@ -67,12 +67,14 @@ #define GPIOPA_AFSEL MEM_ADDR(0x40004420) #define GPIOA_CRH MEM_ADDR(0x40010804) // for USART1 +#define GPIOA_ODR MEM_ADDR(0x4001080C) #define GPIOB_CRL MEM_ADDR(0x40010C00) // low register (!) for I2C1 #define GPIOC_CRL MEM_ADDR(0x40011000) // led +#define GPIOC_CRH MEM_ADDR(0x40011004) #define GPIOC_ODR MEM_ADDR(0x4001100C) -//#define GPIOD_CRL MEM_ADDR(0x40011400) -//#define GPIOD_ODR MEM_ADDR(0x4001140C) +#define GPIOD_CRL MEM_ADDR(0x40011400) +#define GPIOD_ODR MEM_ADDR(0x4001140C) #define AFIO_EVCR MEM_ADDR(0x40010000) @@ -104,6 +106,18 @@ #define RTC_PRLL MEM_ADDR(0x4000280C) #define RTC_CNTH MEM_ADDR(0x40002818) #define RTC_CNTL MEM_ADDR(0x4000281C) - /* BACKUP (CALIBR) REGISTERS */ #define BKP_RTCCR MEM_ADDR(0x40006C2C) // RTC Calibration + +#define TIM4_CR1 MEM_ADDR(0x40000800) +#define TIM4_RCR MEM_ADDR(0x40000830) +#define TIM4_ARR MEM_ADDR(0x4000082C) +#define TIM4_EGR MEM_ADDR(0x40000814) +#define TIM4_SR1 MEM_ADDR(0x40000810) +#define TIM4_CCR1 MEM_ADDR(0x40000834) +#define TIM4_PSC MEM_ADDR(0x40000828) +#define TIM4_SMCR MEM_ADDR(0x40000808) +#define TIM4_CCER MEM_ADDR(0x40000820) +//#define TIM1_BDTR MEM_ADDR(0x40000844) +#define TIM4_CCMR1 MEM_ADDR(0x40000818) +#define TIM4_DIER MEM_ADDR(0x4000080C) diff --git a/ivt.c b/ivt.c index 9f8e643..02c45ec 100644 --- a/ivt.c +++ b/ivt.c @@ -30,6 +30,7 @@ #include #include #include +#include /* * These values are pushed on the stack just before @@ -92,13 +93,15 @@ char * messages[] = { if (intnr < 20) // TODO: strlen return messages[intnr]; - return NULL; + +return "UNKNOWN"; } void ivt_set_gate(unsigned char num, void * isr(), short pri) { ivt[num] = (uint32_t) isr; - *NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F)); +// if (num <= 32) +// *NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F)); /* TODO: Priorities */ } @@ -106,16 +109,23 @@ void ivt_set_gate(unsigned char num, void * isr(), short pri) { /* Dummy interrupt: comment out the comment to use a naked * function */ -// __attribute__ ((interrupt)) -void * dummy_isr(/* struct interrupt_frame * frame */) { +__attribute__ ((interrupt)) +void * dummy_isr( struct interrupt_frame * frame ) { uint8_t nr = *SCB_VTOR_ST & 0xFF; + //printf("PC:%p\n",frame->lr); + printf("EXCEPTION: %s\n", exception_message(nr)); + printf("STACK TRACE:\n"); + printf("R0:%p\n",frame->r0); + printf("R1:%p\n",frame->r1); + printf("R2:%p\n",frame->r2); + printf("R3:%p\n",frame->r3); + printf("R12:%p\n",frame->r12); + printf("LR:%p\n",frame->lr); + printf("PC:%p\n",frame->pc); + printf("PSR:%p\n",frame->psr); - cputs("EXCEPTION: "); - cputs(exception_message(nr)); - cputs("\nSYSTEM HALTED\n"); - - for(;;); + //for(;;); } /* Initialize interrupt vector */ diff --git a/lib/stdio.c b/lib/stdio.c index ac26165..9ef20ee 100644 --- a/lib/stdio.c +++ b/lib/stdio.c @@ -31,6 +31,12 @@ void cputchar(char c) { } +void putc(void *p, char c) { + + cputchar(c); + +} + void cputs(unsigned char *str) { int i; diff --git a/lib/tinyprintf.c b/lib/tinyprintf.c new file mode 100644 index 0000000..d57128f --- /dev/null +++ b/lib/tinyprintf.c @@ -0,0 +1,521 @@ +/* +File: tinyprintf.c + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include + + +/* + * Configuration + */ + +/* Enable long int support */ +#define PRINTF_LONG_SUPPORT + +/* Enable long long int support (implies long int support) */ +//#define PRINTF_LONG_LONG_SUPPORT + +/* Enable %z (size_t) support */ +#define PRINTF_SIZE_T_SUPPORT + +/* + * Configuration adjustments + */ +#ifdef PRINTF_SIZE_T_SUPPORT +#include +#endif + +#ifdef PRINTF_LONG_LONG_SUPPORT +# define PRINTF_LONG_SUPPORT +#endif + +/* __SIZEOF___ defined at least by gcc */ +#ifdef __SIZEOF_POINTER__ +# define SIZEOF_POINTER __SIZEOF_POINTER__ +#endif +#ifdef __SIZEOF_LONG_LONG__ +# define SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__ +#endif +#ifdef __SIZEOF_LONG__ +# define SIZEOF_LONG __SIZEOF_LONG__ +#endif +#ifdef __SIZEOF_INT__ +# define SIZEOF_INT __SIZEOF_INT__ +#endif + +#ifdef __GNUC__ +# define _TFP_GCC_NO_INLINE_ __attribute__ ((noinline)) +#else +# define _TFP_GCC_NO_INLINE_ +#endif + +/* + * Implementation + */ +struct param { + char lz:1; /**< Leading zeros */ + char alt:1; /**< alternate form */ + char uc:1; /**< Upper case (for base16 only) */ + char align_left:1; /**< 0 == align right (default), 1 == align left */ + unsigned int width; /**< field width */ + char sign; /**< The sign to display (if any) */ + unsigned int base; /**< number base (e.g.: 8, 10, 16) */ + char *bf; /**< Buffer to output */ +}; + + +#ifdef PRINTF_LONG_LONG_SUPPORT +static void _TFP_GCC_NO_INLINE_ ulli2a( + unsigned long long int num, struct param *p) +{ + int n = 0; + unsigned long long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void lli2a(long long int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ulli2a(num, p); +} +#endif + +#ifdef PRINTF_LONG_SUPPORT +static void uli2a(unsigned long int num, struct param *p) +{ + int n = 0; + unsigned long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void li2a(long num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + uli2a(num, p); +} +#endif + +static void ui2a(unsigned int num, struct param *p) +{ + int n = 0; + unsigned int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void i2a(int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ui2a(num, p); +} + +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 a2u(char ch, const char **src, int base, unsigned int *nump) +{ + const char *p = *src; + unsigned 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, struct param *p) +{ + char ch; + int n = p->width; + char *bf = p->bf; + + /* Number of filling characters */ + while (*bf++ && n > 0) + n--; + if (p->sign) + n--; + if (p->alt && p->base == 16) + n -= 2; + else if (p->alt && p->base == 8) + n--; + + /* Fill with space to align to the right, before alternate or sign */ + if (!p->lz && !p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } + + /* print sign */ + if (p->sign) + putf(putp, p->sign); + + /* Alternate */ + if (p->alt && p->base == 16) { + putf(putp, '0'); + putf(putp, (p->uc ? 'X' : 'x')); + } else if (p->alt && p->base == 8) { + putf(putp, '0'); + } + + /* Fill with zeros, after alternate or sign */ + if (p->lz) { + while (n-- > 0) + putf(putp, '0'); + } + + /* Put actual buffer */ + bf = p->bf; + while ((ch = *bf++)) + putf(putp, ch); + + /* Fill with space to align to the left, after string */ + if (!p->lz && p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } +} + +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va) +{ + struct param p; +#ifdef PRINTF_LONG_SUPPORT + char bf[23]; /* long = 64b on some architectures */ +#else + char bf[12]; /* int = 32b on some architectures */ +#endif + char ch; + p.bf = bf; + + while ((ch = *(fmt++))) { + if (ch != '%') { + putf(putp, ch); + } else { +#ifdef PRINTF_LONG_SUPPORT + char lng = 0; /* 1 for long, 2 for long long */ +#endif + /* Init parameter struct */ + p.lz = 0; + p.alt = 0; + p.width = 0; + p.align_left = 0; + p.sign = 0; + + /* Flags */ + while ((ch = *(fmt++))) { + switch (ch) { + case '-': + p.align_left = 1; + continue; + case '0': + p.lz = 1; + continue; + case '#': + p.alt = 1; + continue; + default: + break; + } + break; + } + + /* Width */ + if (ch >= '0' && ch <= '9') { + ch = a2u(ch, &fmt, 10, &(p.width)); + } + + /* We accept 'x.y' format but don't support it completely: + * we ignore the 'y' digit => this ignores 0-fill + * size and makes it == width (ie. 'x') */ + if (ch == '.') { + p.lz = 1; /* zero-padding */ + /* ignore actual 0-fill size: */ + do { + ch = *(fmt++); + } while ((ch >= '0') && (ch <= '9')); + } + +#ifdef PRINTF_SIZE_T_SUPPORT +# ifdef PRINTF_LONG_SUPPORT + if (ch == 'z') { + ch = *(fmt++); + if (sizeof(size_t) == sizeof(unsigned long int)) + lng = 1; +# ifdef PRINTF_LONG_LONG_SUPPORT + else if (sizeof(size_t) == sizeof(unsigned long long int)) + lng = 2; +# endif + } else +# endif +#endif + +#ifdef PRINTF_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 1; +#ifdef PRINTF_LONG_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 2; + } +#endif + } +#endif + switch (ch) { + case 0: + goto abort; + case 'u': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'd': + case 'i': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + lli2a(va_arg(va, long long int), &p); + else +#endif + if (1 == lng) + li2a(va_arg(va, long int), &p); + else +#endif + i2a(va_arg(va, int), &p); + putchw(putp, putf, &p); + break; +#ifdef SIZEOF_POINTER + case 'p': + p.alt = 1; +# if defined(SIZEOF_INT) && SIZEOF_POINTER <= SIZEOF_INT + lng = 0; +# elif defined(SIZEOF_LONG) && SIZEOF_POINTER <= SIZEOF_LONG + lng = 1; +# elif defined(SIZEOF_LONG_LONG) && SIZEOF_POINTER <= SIZEOF_LONG_LONG + lng = 2; +# endif +#endif + case 'x': + case 'X': + p.base = 16; + p.uc = (ch == 'X')?1:0; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'o': + p.base = 8; + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'c': + putf(putp, (char)(va_arg(va, int))); + break; + case 's': + p.bf = va_arg(va, char *); + putchw(putp, putf, &p); + p.bf = bf; + break; + case '%': + putf(putp, ch); + default: + break; + } + } + } + abort:; +} + +#if TINYPRINTF_DEFINE_TFP_PRINTF +static putcf stdout_putf; +static void *stdout_putp; + +void init_printf(void *putp, putcf putf) +{ + stdout_putf = putf; + stdout_putp = putp; +} + +void tfp_printf(char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + tfp_format(stdout_putp, stdout_putf, fmt, va); + va_end(va); +} +#endif + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +struct _vsnprintf_putcf_data +{ + size_t dest_capacity; + char *dest; + size_t num_chars; +}; + +static void _vsnprintf_putcf(void *p, char c) +{ + struct _vsnprintf_putcf_data *data = (struct _vsnprintf_putcf_data*)p; + if (data->num_chars < data->dest_capacity) + data->dest[data->num_chars] = c; + data->num_chars ++; +} + +int tfp_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + struct _vsnprintf_putcf_data data; + + if (size < 1) + return 0; + + data.dest = str; + data.dest_capacity = size-1; + data.num_chars = 0; + tfp_format(&data, _vsnprintf_putcf, format, ap); + + if (data.num_chars < data.dest_capacity) + data.dest[data.num_chars] = '\0'; + else + data.dest[data.dest_capacity] = '\0'; + + return data.num_chars; +} + +int tfp_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsnprintf(str, size, format, ap); + va_end(ap); + return retval; +} + +struct _vsprintf_putcf_data +{ + char *dest; + size_t num_chars; +}; + +static void _vsprintf_putcf(void *p, char c) +{ + struct _vsprintf_putcf_data *data = (struct _vsprintf_putcf_data*)p; + data->dest[data->num_chars++] = c; +} + +int tfp_vsprintf(char *str, const char *format, va_list ap) +{ + struct _vsprintf_putcf_data data; + data.dest = str; + data.num_chars = 0; + tfp_format(&data, _vsprintf_putcf, format, ap); + data.dest[data.num_chars] = '\0'; + return data.num_chars; +} + +int tfp_sprintf(char *str, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsprintf(str, format, ap); + va_end(ap); + return retval; +} +#endif diff --git a/main.c b/main.c index ccf6015..38f9a37 100644 --- a/main.c +++ b/main.c @@ -19,10 +19,12 @@ #include #include +#include #include #include #include +#include //void sleep() { // @@ -39,7 +41,9 @@ void main() systick_init(); led_init(); rtc_init(); + tsensor_init(); + init_printf(NULL, putc); // SPEED_TEST /* cputs("START TEST (8MHz) \n"); int a; diff --git a/rtc.c b/rtc.c index 9ffffc7..4877d92 100644 --- a/rtc.c +++ b/rtc.c @@ -18,19 +18,22 @@ #include #include +#include + static void periodic_intr() { while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated - rsetbit(RTC_CRL, 4); + rsetbit(RTC_CRL, 4); // start configure rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt while(!rchkbit(RTC_CRL, 5)); rwrite(RTC_PRLL, 0x7FFF); // 1 second - rclrbit(RTC_CRL, 4); + rclrbit(RTC_CRL, 4); // stop configure while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated + rsetbit(NVIC_ISER0, 3); // enable in register vector } static void calibrate_rtc() { @@ -49,6 +52,10 @@ static void calibrate_rtc() { void * rtc_handler() { //cputs("TICKING IN REAL TIME\n"); + //uint32_t curr = *RTC_CNTL; + int even = *RTC_CNTL % 2; + (!even) ? led_off() : led_on(); + rclrbit(RTC_CRL, 0); } diff --git a/term.c b/term.c index dba355b..9be55e4 100644 --- a/term.c +++ b/term.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -44,9 +45,10 @@ int info(int argc, char ** argsv) { } int uptime(int arg, char ** argsv) { - cputs("CURRENT UPTIME: "); - cputs(regtohex(*RTC_CNTL)); - cputchar('\n'); + //cputs("CURRENT UPTIME: "); + //cputs(regtohex(*RTC_CNTL)); + //cputchar('\n'); + printf("CURRENT UPTIME: %p\n", *RTC_CNTL); } int led(int argc, char ** argsv) {