tm1637 signs of life, terminal builtin cmds
authorRobin Krens <robin@robinkrens.nl>
Sun, 28 Jul 2019 20:00:58 +0000 (04:00 +0800)
committerRobin Krens <robin@robinkrens.nl>
Sun, 28 Jul 2019 20:00:58 +0000 (04:00 +0800)
drivers/tm1637.c
drivers/uart.c
include/drivers/tm1637.h
include/lib/regfunc.h
include/lib/string.h
include/sys/mmap.h
lib/regfunc.c
lib/string.c
main.c
sysinfo.c
term.c

index a4e3842..517e0cf 100644 (file)
@@ -5,8 +5,13 @@
  * Initial version 
  * 
  * $DESCRIPTION$
- * Basic driver for the TM1637. The TM1637 is 7 segment
- * ledclock peripheral. Communication is over I2C.
+ * Basic driver for the TM1637. The TM1637 is 8 segment
+ * ledclock peripheral. Communication is similar to I2C,
+ * but not completely. There is no address selecting.
+ *
+ * Alternative I2C protocol : (W)rite or (R)ead
+ * | Start | ADDRESS | W | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
+ * | Start | ADDRESS | R | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
  *
  * */
 
 
 #include <lib/regfunc.h>
 #include <lib/string.h>
+#include <lib/stdio.h>
 
 #include <drivers/tm1637.h>
 
+#define TIMEOUT 1000
+
+#define DATASET        0x40
+#define CONTROL        0x80
+#define SETADDR        0xC0
+
+#define DISPLAY_ON     0x8F
+#define DISPLAY_OFF    0x11
+
+/* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
+GPIOs must be configured as open-drain. So, you have to add two additional resistors to
+pull-up I2C lines. Something between 4K and 10K is a proven value.
+*/
 
 void tm1637_init() {
 
  /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
- Configure the clock control registers
- Configure the rise time register
+ Configure the clock control registers CCR
+ Configure the rise time register TRIS
  Program the I2C_CR1 register to enable the peripheral
- Set the START bit in the I2C_CR1 register to generate a Start condition 
 
  ENABLE GPIOB6 and B7*/
 
//regw_u8(RCC_APB1ENR, 0x1, 21, SETBIT);
//regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
+ regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
  // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
  
- // regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
+ regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
+
+ regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz 
+ regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1)
+ regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard modeļ¼Œ output 100 kHz (100hz* / perip)
  
+ regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable
+
+}
+
+static void start_condition() {
+
+       regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
+
+}
+
+static void stop_condition() {
+
+       regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
+}
+
+int ack_recv() {
+
+       int cnt = 0;
+       while(!(*I2C_SR1 & 0x1)) {
+               cnt++;
+               if (cnt > TIMEOUT)
+                       return 0;
+       }
+
+       return 1;
+
+}
+
+int delay() {
+
+       int a = 0;
+       for (int i = 0; i < TIMEOUT; i++)
+               a++;
+}
+
+void tm1637_start() {
+
+//     regw_u32(I2C_CR1, 0x1, 8, SETBIT);
+//     uint32_t read_status = *I2C_SR1;
+
+//     regw_u32(I2C_DR, DATASET, 0, OWRITE); 
+       // conform DATA
+//     read_status = *I2C_SR1;
+//     read_status = *I2C_SR2;
+
+       uint32_t statusr;
+
+       start_condition();
+       //uint32_t statusr = *I2C_SR1; // clear start_signal
+       regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
+       if(!ack_recv())
+               cputs("TIMEOUT!");
+       //statusr = *I2C_SR1;
+       //statusr = *I2C_SR2;
+       stop_condition();
+
+       //delay();
+
+       start_condition();
+       //statusr = *I2C_SR1; // clear start_signal
+       regw_u32(I2C_DR, 0xC1, 0, OWRITE);
+       if(!ack_recv())
+               cputs("TIMEOUT2!");
+       //statusr = *I2C_SR1;
+       //statusr = *I2C_SR2;
+       regw_u32(I2C_DR, 0x7D, 0, OWRITE);
+       if(!ack_recv())
+               cputs("TIMEOUT3!");
+       stop_condition();
+
+       delay();
+
+       start_condition();
+       statusr = *I2C_SR1;
+       regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
+       if(!ack_recv())
+               cputs("TIMEOUT4!");
+       stop_condition();
+
+
+       /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
+       uint32_t read_status = *I2C_SR1; 
+       regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
+       read_status = *I2C_SR1;
+       read_status = *I2C_SR2;
+       regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
+       read_status = *I2C_SR1;
+
+       regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
+       read_status = *I2C_SR1;
+       regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
+       read_status = *I2C_SR1;
+       read_status = *I2C_SR2;
+       regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
+
+       regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
+       read_status = *I2C_SR1;
+
+       regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
+       read_status = *I2C_SR1;
+
+       regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
+       read_status = *I2C_SR1;
+       regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
 
 }
 
+void tm1637_stop() {
+
+       //regw_u32(I2C_CR1, 0x0, 9, SETBIT);
+}
+
+
+
index a107548..4693c6f 100644 (file)
@@ -75,7 +75,7 @@ static void wait() {
        for (int i = 0; i < 100; i++);
 }
 
-extern void uart_putc(unsigned char ch) {
+void uart_putc(unsigned char ch) {
        
        if (ch == '\n') {
                while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
@@ -102,10 +102,10 @@ char uart_getc(void) {
 
 
 // move to library 
-extern void uart_puts(unsigned char *str) {
+/* extern void uart_puts(unsigned char *str) {
     int i;
     for (i = 0; i < strlen(str); i++)     {
         uart_putc(str[i]);
     }
-}
+} */
 
index 319d5c5..4ad572a 100644 (file)
@@ -2,5 +2,7 @@
 #define __TM1637_H
 
 extern void tm1637_init();
+extern void tm1637_start();
+extern void tm1637_stop();
 
 #endif
index 6b0c50b..f194df0 100644 (file)
@@ -1,4 +1,5 @@
 /* regfunc.h */
 extern char * regtohex(uint32_t );
+extern uint32_t hextoreg(char *);
 extern void regw_u8(volatile uint32_t *, uint8_t, short, short);
 extern void regw_u32(volatile uint32_t *, uint32_t, short, short);
index e8e52f7..d19522b 100644 (file)
@@ -3,3 +3,5 @@ extern void *memcpy(void*, void*, size_t);
 extern void *memset(void*, unsigned char, size_t);
 extern unsigned short *memsetw(unsigned short *dest, unsigned short val, size_t count);
 extern int strlen(const char *);
+extern int strcmp(char *, char *);
+extern char * strchr(const char *, char);
index c3c91a1..4fd043d 100644 (file)
 
 #define AFIO_EVCR MEM_ADDR(0x40010000)
 
+/* I2C REGISTER */
+#define I2C_CR1 MEM_ADDR(0x40005400)
+#define I2C_CR2 MEM_ADDR(0x40005404)
+#define I2C_DR MEM_ADDR(0x40005410)
+#define I2C_SR1 MEM_ADDR(0x40005414)
+#define I2C_SR2 MEM_ADDR(0x40005418)
+#define I2C_CCR MEM_ADDR(0x4000541C)
+#define I2C_TRISE MEM_ADDR(0x40005420)
+
 /* EXTERNAL INTERRUPTS */
 #define EXTI_IMR MEM_ADDR(0x40010400)
 #define EXTI_RTSR MEM_ADDR(0x40010408)
index 6add220..b783901 100644 (file)
@@ -40,8 +40,7 @@ void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) {
 }
 
 /* Print out the hexidecimal representation of an integer
-   After implementation of a printf function, this code
-   will be obsolete.  */
+   After implementation of scanf or sth this will be obsolete.  */
 
 char hexbuf[8];
 char * regtohex(uint32_t addr) {
@@ -62,3 +61,28 @@ char * regtohex(uint32_t addr) {
        }
        return &hexbuf[0];      
 }
+int singlehextoreg(char  hex) {
+
+       int conv = 0;
+       if (hex >= 'A' && hex <= 'F') 
+               conv = hex - '7';
+
+       else {
+               conv = hex - '0';
+       }
+       return conv;
+
+}
+
+uint32_t hextoreg(char * a) {
+       
+       uint32_t x = 0;
+       int tmp;
+       for(int i = 0; i < 8; i++) {
+               tmp = singlehextoreg(*a++);
+               x += tmp << (28 - (i * 4));
+       }
+       return x;
+
+}
+
index b1618b0..2edc71a 100644 (file)
@@ -36,3 +36,26 @@ int strlen(const char *str)
     for(retval = 0; *str != '\0'; str++) retval++;
     return retval;
 }
+
+int strcmp(char * a, char * b) {
+
+       int alen = strlen(a);
+       int blen = strlen(b);
+
+       if (alen != blen)
+               return 0;
+
+       for (; alen != 0; alen--) {
+                       if (*a++ != *b++)
+                               return 0;
+       }
+       return 1;
+}
+
+char * strchr(const char *s, char c) {
+         for (; *s; s++)
+                 if (*s == c)
+                         return (char *) s;
+         return 0;
+}
+
diff --git a/main.c b/main.c
index c5ee202..342059e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -17,6 +17,9 @@
 #include <sys/robsys.h> 
 #include <sys/mmap.h>
 
+#include <lib/regfunc.h>
+#include <lib/stdio.h>
+
 #include <drivers/uart.h>
 #include <drivers/led.h>
 #include <drivers/tm1637.h>
 void main()
 {
        ivt_init();
-       
        uart_init();
+//     cputs("ROBSYS LOADING...\n");
        systick_init();
-
        led_init();
-       
        sysinfo();
 
+       tm1637_init();
+       tm1637_start();
+
+       //uint32_t test = hextoreg("12345678");
+               
+//     cputs(regtohex(test));
+
        //extern void stub();
        //stub();
        //__asm__ __volatile__ ("ldc p1, cr1, r0");
 
-       while(1) {
+/*     while(1) {
                int r;
                for (int i = 0; i < 50000; i++) {
                        r = 0;  
@@ -46,8 +54,8 @@ void main()
                        r = 0;  
                }
                led_off();
-       }
-       // terminal();
+       } */
+       terminal();
 
        for(;;) {
 
index ba639a6..7f06334 100644 (file)
--- a/sysinfo.c
+++ b/sysinfo.c
@@ -22,7 +22,6 @@ uint32_t get_msp(void);
 void sysinfo() {
 
        uint32_t tmp = *MCU_ID;
-       cputs("# ROBSYS 0.1 LOADING...\n");
        cputs("# DEVICE ID: ");
 
        if (tmp & 0x414) 
diff --git a/term.c b/term.c
index 0628e1e..51eb9cf 100644 (file)
--- a/term.c
+++ b/term.c
@@ -6,10 +6,16 @@
 #include <sys/mmap.h>
 
 #include <lib/stdio.h>
+#include <lib/string.h>
+#include <lib/regfunc.h>
+
+#include <drivers/led.h>
 
 #define SERIAL 1
 #define BUFSIZE 200
-
+#define MAXARGS 5
+#define WHITESPACE "\t\r\n "
+#define BUILTINCMDS 3
 
 int help(int, char**);
 
@@ -26,27 +32,107 @@ static char buf[BUFSIZE];
 
 struct cmd {
        char * name;
-       char * description;
        int (*function)(int argc, char ** argsv);
 };
 
-static struct cmd builtin[] = 
-       { "info", "show info", help};
+struct cmd builtincmds[4];
 
 int help(int argc, char ** argsv) {
        sysinfo();
        return 0;
 }
 
+int led(int argc, char ** argsv) {
+
+
+       if (argsv[1] != NULL) {
+               if (strcmp(argsv[1], "on")) {
+                       cputs("LED ON\n");
+                       led_on();
+                       }
+               else if (strcmp(argsv[1], "off")) {
+                       cputs("LED OFF\n");
+                       led_off();
+                       }
+       }
+       return 0;
+}
+
+int show(int argc, char ** argsv) {
+
+       if ((argsv[1] != NULL) && (strlen(argsv[1]) == 8)) {
+       
+               uint32_t * check = (uint32_t *) hextoreg(argsv[1]);
+               cputs("REGISTER 0x");
+               cputs(argsv[1]);
+               cputs(" VALUE: ");
+               cputs(regtohex(*check));
+               cputchar('\n');
+               return 1;
+       
+       }
+
+       return 0;
+}
+
+int exec_cmd(char * buf) {
+
+       int argc;
+       char *argv[MAXARGS];
+       int i;
+
+       // Parse the command buffer into whitespace-separated arguments
+       argc = 0;
+       argv[argc] = 0;
+       while (1) {
+               // gobble whitespace
+               while (*buf && strchr(WHITESPACE, *buf))
+                       *buf++ = 0;
+               if (*buf == 0)
+                       break;
+
+               // save and scan past next arg
+               if (argc == MAXARGS-1) {
+                       cputs("Too many arguments");
+                       return 0;
+               }
+               argv[argc++] = buf;
+               while (*buf && !strchr(WHITESPACE, *buf))
+                       buf++;
+       }
+       argv[argc] = 0;
+
+       // Lookup and invoke the command
+       if (argc == 0)
+               return 0;
+       for (i = 0; i < BUILTINCMDS; i++) {
+               if (strcmp(argv[0], builtincmds[i].name))
+                       return builtincmds[i].function(argc, argv);
+       }
+       cputs("Unknown command");
+       return 0;
+
+} 
+
 void terminal() {
+
+               builtincmds[0].name = "help";
+       builtincmds[0].function = help;
+
+       builtincmds[1].name = "led";
+       builtincmds[1].function = led;
+
+       builtincmds[2].name = "show";
+       builtincmds[2].function = show;
+
        char *buf;
-        cputs("Terminal running!\n");
+        cputs("WELCOME TO ROBSYS!\n");
  
          while (1) {
                  buf = readline("root# ");
-                 /* if (buf != NULL)
-                         if (runcmd(buf, tf) < 0)
-                                 break; */
+                       if (buf != NULL)
+                         if (exec_cmd(buf) < 0)
+                                 break;
          }
 }
+