pretty print EEPROM
[cortex-from-scratch] / drivers / tm1637.c
1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
2  * 
3  * $LOG$
4  * 2019/7/25 - ROBIN KRENS      
5  * Initial version 
6  * 
7  * $DESCRIPTION$
8  * Basic driver for the TM1637. The TM1637 is 8 segment
9  * ledclock peripheral. Communication is similar to I2C,
10  * but not completely. There is no address selecting.
11  *
12  * Alternative I2C protocol : (W)rite or (R)ead
13  * | Start | ADDRESS | W | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
14  * | Start | ADDRESS | R | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
15  *
16  * */
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21
22 #include <sys/mmap.h>
23 #include <sys/robsys.h>
24
25 #include <lib/regfunc.h>
26 #include <lib/string.h>
27 #include <lib/stdio.h>
28
29 #include <drivers/tm1637.h>
30
31 #define TIMEOUT 5000
32
33 #define DATASET 0x40
34 #define CONTROL 0x80
35 #define SETADDR 0xC0
36
37 #define DISPLAY_ON      0x8F
38 #define DISPLAY_OFF     0x11
39
40 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
41 GPIOs must be configured as open-drain. So, you have to add two additional resistors to
42 pull-up I2C lines. Something between 4K and 10K is a proven value.
43 */
44
45 void tm1637_init() {
46
47  /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
48  Configure the clock control registers CCR
49  Configure the rise time register TRIS
50  Program the I2C_CR1 register to enable the peripheral
51
52  ENABLE GPIOB6 and B7*/
53
54  regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
55  regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
56  // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
57  
58  regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
59
60  regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz 
61  regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1)
62  regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard modeļ¼Œ output 100 kHz (100hz* / perip)
63  
64  regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable
65
66 }
67
68 static void start_condition() {
69
70         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
71
72 }
73
74 static void stop_condition() {
75
76         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
77 }
78
79 int ack_recv() {
80
81         int cnt = 0;
82         while(!(*I2C_SR1 & 0x2)) {
83                 cnt++;
84                 if (cnt > TIMEOUT)
85                         return 0;
86         }
87
88         return 1;
89
90 }
91
92 int buf_empty() {
93         int cnt = 0;
94         while(!(*I2C_SR1 & 0x80)) {
95                 cnt++;
96                 if (cnt > TIMEOUT)
97                         return 0;
98         }
99
100         return 1;
101 }
102
103 int delay() {
104
105         int a = 0;
106         for (int i = 0; i < TIMEOUT; i++)
107                 a++;
108 }
109
110 void tm1637_start() {
111
112 //      regw_u32(I2C_CR1, 0x1, 8, SETBIT);
113 //      uint32_t read_status = *I2C_SR1;
114
115 //      regw_u32(I2C_DR, DATASET, 0, OWRITE); 
116         // conform DATA
117 //      read_status = *I2C_SR1;
118 //      read_status = *I2C_SR2;
119
120         uint32_t statusr;
121
122         start_condition();
123         //uint32_t statusr = *I2C_SR1; // clear start_signal
124         regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
125         if(!ack_recv())
126                 cputs("TIMEOUT!");
127         //statusr = *I2C_SR1;
128         //statusr = *I2C_SR2;
129         stop_condition();
130
131         //delay();
132
133         start_condition();
134         //statusr = *I2C_SR1; // clear start_signal
135         regw_u32(I2C_DR, 0xC1, 0, OWRITE);
136         if(!ack_recv())
137                 cputs("TIMEOUT2!");
138         //statusr = *I2C_SR1;
139         //statusr = *I2C_SR2;
140         regw_u32(I2C_DR, 0x7D, 0, OWRITE);
141         if(!buf_empty())
142                 cputs("TIMEOUT3!");
143         stop_condition();
144
145 /*      delay();
146
147         start_condition();
148         statusr = *I2C_SR1;
149         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
150         if(!ack_recv())
151                 cputs("TIMEOUT4!");
152         stop_condition(); */
153
154
155         /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
156         uint32_t read_status = *I2C_SR1; 
157         regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
158         read_status = *I2C_SR1;
159         read_status = *I2C_SR2;
160         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
161         read_status = *I2C_SR1;
162
163         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
164         read_status = *I2C_SR1;
165         regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
166         read_status = *I2C_SR1;
167         read_status = *I2C_SR2;
168         regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
169
170         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
171         read_status = *I2C_SR1;
172
173         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
174         read_status = *I2C_SR1;
175
176         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
177         read_status = *I2C_SR1;
178         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
179
180 }
181
182 void tm1637_stop() {
183
184         //regw_u32(I2C_CR1, 0x0, 9, SETBIT);
185 }
186
187
188