basic implemtation general purpose clock and tinyprintf
authorRobin Krens <robin@robinkrens.nl>
Mon, 5 Aug 2019 14:29:35 +0000 (22:29 +0800)
committerRobin Krens <robin@robinkrens.nl>
Mon, 5 Aug 2019 14:29:35 +0000 (22:29 +0800)
TIM4 used as general purpose timer; output mode; sends out continous
pulses over GPIOB6. Implementation tinyprintf library (not all converted
yet).

14 files changed:
Makefile
drivers/led.c
drivers/tsensor.c [new file with mode: 0644]
drivers/uart.c
include/drivers/tsensor.h [new file with mode: 0644]
include/lib/stdio.h
include/lib/tinyprintf.h [new file with mode: 0644]
include/sys/mmap.h
ivt.c
lib/stdio.c
lib/tinyprintf.c [new file with mode: 0644]
main.c
rtc.c
term.c

index 5cc5791..65c1294 100644 (file)
--- 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
index 0cdda5a..84c4d0a 100644 (file)
 
 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 (file)
index 0000000..499fa45
--- /dev/null
@@ -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 <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/mmap.h>
+#include <sys/robsys.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+#include <lib/tinyprintf.h>
+
+#include <drivers/tsensor.h>
+
+/* 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
+}
+
+
index 05f0406..0090ef2 100644 (file)
@@ -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 (file)
index 0000000..64a5e94
--- /dev/null
@@ -0,0 +1,2 @@
+extern void tsensor_init();
+
index cf3075b..93d1f99 100644 (file)
@@ -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 (file)
index 0000000..8855710
--- /dev/null
@@ -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 <stdarg.h>
+
+/* 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 <sys/types.h>  /* 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
index 6dda221..ee0da1e 100644 (file)
 #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)
 
 #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 (file)
--- a/ivt.c
+++ b/ivt.c
@@ -30,6 +30,7 @@
 #include <lib/stdio.h>
 #include <lib/string.h>
 #include <lib/regfunc.h>
+#include <lib/tinyprintf.h>
 
 /* 
  * 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  */
index ac26165..9ef20ee 100644 (file)
@@ -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 (file)
index 0000000..d57128f
--- /dev/null
@@ -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 <lib/tinyprintf.h>
+
+
+/*
+ * 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 <sys/types.h>
+#endif
+
+#ifdef PRINTF_LONG_LONG_SUPPORT
+# define PRINTF_LONG_SUPPORT
+#endif
+
+/* __SIZEOF_<type>__ 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 (file)
--- a/main.c
+++ b/main.c
 
 #include <lib/regfunc.h>
 #include <lib/stdio.h>
+#include <lib/tinyprintf.h>
 
 #include <drivers/uart.h>
 #include <drivers/led.h>
 #include <drivers/tm1637.h>
+#include <drivers/tsensor.h>
 
 //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 (file)
--- a/rtc.c
+++ b/rtc.c
 #include <lib/regfunc.h>
 #include <lib/stdio.h>
 
+#include <drivers/led.h>
+
 
 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 (file)
--- a/term.c
+++ b/term.c
@@ -8,6 +8,7 @@
 #include <lib/stdio.h>
 #include <lib/string.h>
 #include <lib/regfunc.h>
+#include <lib/tinyprintf.h>
 
 #include <drivers/led.h>
 
@@ -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) {