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)
1  2 
drivers/tm1637.c
include/sys/mmap.h
include/sys/robsys.h
main.c

diff --combined drivers/tm1637.c
  
  #include <drivers/tm1637.h>
  
 -#define TIMEOUT 1000
 +#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
  
  }
  
+ 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 +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,86 +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);
  
+ }
  
  
diff --combined include/sys/mmap.h
  
  /* SYSTEM INFO AND DEBUG */
  #define MCU_ID MEM_ADDR(0xE000ED00) 
 -#define FLASH_MEM MEM_ADDR(0x1FFFF000) 
 +#define FLASH_MEM MEM_ADDR(0x1FFFF000)
 +
 +/* POWER CONTROL REGISTERS */
 +#define PWR_CR MEM_ADDR(0x40007000)
  
  /* SYSTEM CONTROL BLOCK REGISTER */
  #define SCB_VTOR MEM_ADDR(0xE000ED08) // VECTOR TABLE
  /* SYSTICK REGISTER */
  #define STK_CTRL MEM_ADDR(0xE000E010)
  #define STK_RELOAD MEM_ADDR(0xE000E014)
 +#define STK_CALIB MEM_ADDR(0xE000E01C)
  
 -/* CLOCK REGISTER */
 +/* RESET AND CLOCK REGISTER */
  #define RCC_CR MEM_ADDR(0x40021000)
  #define RCC_CFGR MEM_ADDR(0x40021004)
 +#define RCC_BDCR MEM_ADDR(0x40021020)
  
  /* 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)
  #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) // for led
 -#define GPIOC_ODR MEM_ADDR(0x4001100C) //
 +#define GPIOB_BSRR MEM_ADDR(0x40010C10)
 +#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 AFIO_EVCR MEM_ADDR(0x40010000)
  
  #define USART1_CR1 MEM_ADDR(0x4001380C)
  #define USART1_CR2 MEM_ADDR(0x40013810)
  #define USART1_CR3 MEM_ADDR(0x40013814)
 +
 +/* REAL TIME CLOCK REGISTERS */
 +#define RTC_CRH MEM_ADDR(0x40002800) // interrupts
 +#define RTC_CRL MEM_ADDR(0x40002804)
 +#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_CCR2 MEM_ADDR(0x40000838)
 +#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 --combined include/sys/robsys.h
@@@ -1,23 -1,8 +1,23 @@@
  #ifndef __SYSTEM_H
  #define __SYSTEM_H
  
 -/* CLOCK.C */
 +
 +/* CLOCK.C 
 + * Board specific clock settings. These boards often come with two 
 + * external oscillators: one high speed (8MHz) and one low speed (~30kHz).
 + * 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();
 +// extern int clock_test();
 +// extern void clock_reset();
 +
 +/* RTC.C */
 +#define ENABLE_RTC    
 +extern void rtc_init();
  
  /* IVT.C */
  extern void ivt_init();
@@@ -29,6 -14,12 +29,6 @@@ extern void systick_init()
  /* SYSINFO.C */
  extern void sysinfo();
  
 -/* MM.C DELETE TODO */
 -//extern void mm_init();
 -//extern void * malloc(size_t);
 -//extern void free(void *);
 -//extern void test_memory(uint32_t *);
 -
  /* POOL.c */
  extern void pool_init(size_t, unsigned int, uint32_t *);
  extern void * alloc();
diff --combined main.c
--- 1/main.c
--- 2/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/at24c.h>
 +#include <drivers/tsensor.h>
 +
 +//void sleep() {
 +//
 +//    __asm__ __volatile__("wfe");
 +//
 +//}
  
  void main()
  {
 +      clock_init();
        ivt_init();
        uart_init();
  //    cputs("ROBSYS LOADING...\n");
 -      systick_init();
 -      led_init();
 +      //systick_init();
 +//    tsensor_output(0xFFFF, 0x7FFF);
 +
 +      init_printf(NULL, putc);
 +      // SPEED_TEST
 +/*    cputs("START TEST (8MHz) \n");
 +      int a;
 +      for (int i = 0; i < 20000000; i++) {
 +              a + 2;  
 +      }
 +      a = 0;
 +      cputs("END TEST\n");
 +      
 +      //! 
 +      clock_init();
 +
 +      cputs("START TEST (??MHz) \n");
 +      for (int i = 0; i < 20000000; i++) {
 +              a + 2;  
 +      }
 +      cputs("END TEST\n"); */
        sysinfo();
  
-       eeprom_at24c_init();
-       eeprom_test();
 +
 +//    tsensor_input(5000);
 +//    run();
 +
 +      led_init();
- //    tm1637_init();
- //    tm1637_start();
++//    eeprom_at24c_init();
++//    eeprom_test();
 +//    rtc_init();
 +
+       tm1637_init();
+       tm1637_start();
  
        //uint32_t test = hextoreg("12345678");