Merge branch 'tm1637'
authorRobin Krens <robin@robinkrens.nl>
Tue, 13 Aug 2019 16:49:37 +0000 (00:49 +0800)
committerRobin Krens <robin@robinkrens.nl>
Tue, 13 Aug 2019 16:49:37 +0000 (00:49 +0800)
drivers/tm1637.c
include/sys/mmap.h
include/sys/robsys.h
main.c

index a2889fd..8c8ce5b 100644 (file)
 
 #define TIMEOUT 5000
 
-#define DATASET        0x40
-#define CONTROL        0x80
-#define SETADDR        0xC0
-
-#define DISPLAY_ON     0x8F
-#define DISPLAY_OFF    0x11
+#define DOT true
+#define NODOT false
+
+
+/* 
+0 = 0x00
+1 = 0x60
+2 = 0xDA
+3 = 0xF2
+4 = 0x66
+5 = 0xB6
+6 = 0xBE
+7 = 0xE0
+8 = 0xFF
+9 = 0xF6
+*/
 
 /* 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.
 */
 
+/* BIG ENDIAN! */
+
 void tm1637_init() {
 
  /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
@@ -65,6 +77,26 @@ void tm1637_init() {
 
 }
 
+void tm1637_reset() {
+
+ regw_u32(RCC_APB1RSTR, 0x1, 21, SETBIT);
+
+ regw_u32(RCC_APB1RSTR, 0x00000000, 0, OWRITE); // clr
+ //regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
+ // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
+ regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
+ //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
@@ -76,22 +108,45 @@ static void stop_condition() {
        regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
 }
 
-int ack_recv() {
+static int buf_empty() {
+        int cnt = 0;
+        while(!(*I2C_SR1 & 0x80)) {
+                cnt++;
+                if (cnt > TIMEOUT) {
+                        return 0;
+                }
+        }
+        return 1;
+}
 
+/* Wait for an acknowledge from the peripheral */
+int ack_recv() {
        int cnt = 0;
        while(!(*I2C_SR1 & 0x2)) {
                cnt++;
                if (cnt > TIMEOUT)
                        return 0;
        }
+       uint32_t a = *I2C_SR2; // need to read SR2 register!
+       return 1;
 
+}
+
+/* Similar, but SR2 register is not read */
+int ack10_recv() {
+       int cnt = 0;
+       while(!(*I2C_SR1 & 0x8)) {
+               cnt++;
+               if (cnt > TIMEOUT)
+                       return 0;
+       }
        return 1;
 
 }
 
-int buf_empty() {
+int idle() {
        int cnt = 0;
-       while(!(*I2C_SR1 & 0x80)) {
+       while(*I2C_SR2 & 0x2) {
                cnt++;
                if (cnt > TIMEOUT)
                        return 0;
@@ -107,82 +162,85 @@ int delay() {
                a++;
 }
 
-void tm1637_start() {
+void set_display(bool on, uint8_t degree) {
+
+       start_condition();
+
+       regw_u32(I2C_DR, 0xF1, 0, OWRITE);
+       if(!ack_recv())
+               cputs("Can't switch on display!");
+       stop_condition();
+
+       // reset bus
+       regw_u32(I2C_CR1, 0x1, 15, SETBIT);
 
-//     regw_u32(I2C_CR1, 0x1, 8, SETBIT);
-//     uint32_t read_status = *I2C_SR1;
+}
+
+
+void set_segment(int offset, char value, bool dot) {
+
+       int (*ack)() = ack_recv; /* Scary function pointer :D */
 
-//     regw_u32(I2C_DR, DATASET, 0, OWRITE); 
-       // conform DATA
-//     read_status = *I2C_SR1;
-//     read_status = *I2C_SR2;
 
-       uint32_t statusr;
+       if (offset > 3) {
+               cputs("Offset incorrect");
+       }
+
+       if (dot) {
+               value = value | 0x1;
+       }
+       int start_pos_cmd  = 0x03  | (offset & 0x01) << 7 | (offset & 0x2) << 5 ;
 
        start_condition();
-       //uint32_t statusr = *I2C_SR1; // clear start_signal
-       regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
+       regw_u32(I2C_DR, 0x20, 0, OWRITE); 
        if(!ack_recv())
-               cputs("TIMEOUT!");
-       //statusr = *I2C_SR1;
-       //statusr = *I2C_SR2;
+               cputs("Error: initiating write for start segment \n");
+
        stop_condition();
+       
+               if(!idle())
+               cputs("Error: timeout");
 
-       //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(!buf_empty())
-               cputs("TIMEOUT3!");
+       regw_u32(I2C_DR, start_pos_cmd, 0, OWRITE); 
+       if(!ack())
+               cputs("Error: Can't set start segment \n");
+
        stop_condition();
+       regw_u32(I2C_CR1, 0x1, 15, SETBIT);
+
+       tm1637_reset();
 
-/*     delay();
+//     if (value & 0xF0)
+//             ack = &ack10_recv;
 
        start_condition();
-       statusr = *I2C_SR1;
-       regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
+       regw_u32(I2C_DR, value, 0, OWRITE); // use ack10 if higher
        if(!ack_recv())
-               cputs("TIMEOUT4!");
-       stop_condition(); */
+               cputs("Error: can't set location\n");
+       stop_condition(); 
 
+       regw_u32(I2C_CR1, 0x1, 15, SETBIT);
 
-       /* 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;
+       tm1637_reset();
+}
 
-       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;
+void tm1637_start() {
 
-       regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
-       read_status = *I2C_SR1;
-       regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
+unsigned char display_number[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};
 
-}
 
-void tm1637_stop() {
+       char love[4]  = { 0x1C, 0xFC, 0x7C, 0x9E };
+       
+       for (int i = 0; i < 4; i++) {
+               set_segment(i, love[i], NODOT);
+       }
 
-       //regw_u32(I2C_CR1, 0x0, 9, SETBIT);
-}
+       set_display(true, 0);
 
+}
 
 
index db6cf5c..9aae914 100644 (file)
@@ -59,6 +59,7 @@
 /* SYSTEM CONTROL REGISTER */
 #define SYSCTRL_RCC MEM_ADDR(0x40021000)
 #define RCC_APB1ENR MEM_ADDR(0x4002101C) // register to enable I2C
+#define RCC_APB1RSTR MEM_ADDR(0x40021010) // register to reset I2C
 #define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1
 
 #define SYSCTRL_RIS MEM_ADDR(0x400FE050)
index 78aedef..9a19a47 100644 (file)
@@ -8,7 +8,7 @@
  * These values are used throughout the code to calculator desired baud
  * rates etc.
  */
-#define ENABLE_HSE     
+//#define ENABLE_HSE   
 //efine CRYSTAL_MHZ    8
 //efine CLKSPEED_MHZ   72
 extern void clock_init();
diff --git a/main.c b/main.c
index 51c2b10..8455b46 100644 (file)
--- a/main.c
+++ b/main.c
@@ -67,12 +67,12 @@ void main()
 //     run();
 
        led_init();
-       eeprom_at24c_init();
-       eeprom_test();
+//     eeprom_at24c_init();
+//     eeprom_test();
 //     rtc_init();
 
-//     tm1637_init();
-//     tm1637_start();
+       tm1637_init();
+       tm1637_start();
 
        //uint32_t test = hextoreg("12345678");