set address location, reset I2C
[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 1000
32
33 #define DISPLAY_ON      0x8F
34 #define DISPLAY_OFF     0x11
35
36
37 /* 
38 0 = 0x00
39 1 = 0x60
40 2 = 0xDA
41 3 = 0xF2
42 4 = 0x66
43 5 = 0xB6
44 6 = 0xBE
45 7 = 0xE0
46 8 = 0xFF
47 9 = 0xF6
48 */
49
50 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
51 GPIOs must be configured as open-drain. So, you have to add two additional resistors to
52 pull-up I2C lines. Something between 4K and 10K is a proven value.
53 */
54
55 /* BIG ENDIAN! */
56
57 void tm1637_init() {
58
59  /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
60  Configure the clock control registers CCR
61  Configure the rise time register TRIS
62  Program the I2C_CR1 register to enable the peripheral
63
64  ENABLE GPIOB6 and B7*/
65
66  regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
67  regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
68  // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
69  
70  regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
71
72  regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz 
73  regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1)
74  regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard mode, output 100 kHz (100hz* / perip)
75  
76  regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable
77
78 }
79
80 void tm1637_reset() {
81
82  regw_u32(RCC_APB1RSTR, 0x1, 21, SETBIT);
83
84  regw_u32(RCC_APB1RSTR, 0x00000000, 0, OWRITE); // clr
85  //regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
86  // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
87  
88  regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
89  //regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
90
91  regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz 
92  regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1)
93  regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard mode, output 100 kHz (100hz* / perip)
94
95  regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable
96
97
98 }
99
100 static void start_condition() {
101
102         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
103
104 }
105
106 static void stop_condition() {
107
108         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
109 }
110
111 static int buf_empty() {
112         int cnt = 0;
113         while(!(*I2C_SR1 & 0x80)) {
114                 cnt++;
115                 if (cnt > TIMEOUT) {
116                         return 0;
117                 }
118         }
119         return 1;
120 }
121
122 int ack_recv() {
123
124         int cnt = 0;
125         while(!(*I2C_SR1 & 0x2)) {
126                 cnt++;
127                 if (cnt > TIMEOUT)
128                         return 0;
129         }
130         uint32_t a = *I2C_SR2;
131         return 1;
132
133 }
134
135 int ack10_recv() {
136
137         int cnt = 0;
138         while(!(*I2C_SR1 & 0x8)) {
139                 cnt++;
140                 if (cnt > TIMEOUT)
141                         return 0;
142         }
143         //uint32_t a = *I2C_SR2;
144         return 1;
145
146 }
147
148 int idle() {
149         int cnt = 0;
150         while(*I2C_SR2 & 0x2) {
151                 cnt++;
152                 if (cnt > TIMEOUT)
153                         return 0;
154         }
155
156         return 1;
157 }
158
159 int delay() {
160
161         int a = 0;
162         for (int i = 0; i < TIMEOUT; i++)
163                 a++;
164 }
165
166 void set_brightness(uint8_t degree) {
167
168         // set pulse!
169         start_condition();
170 //      regw_u32(I2C_DR, 0xF0, 0, OWRITE);
171   //      if(!ack10_recv())
172 //              cputs("Error: can not set dummy header");
173
174         regw_u32(I2C_DR, 0xF1, 0, OWRITE);
175         if(!ack_recv())
176                 cputs("TIMEOUT3!");
177         stop_condition();
178
179         // reset bus
180         regw_u32(I2C_CR1, 0x1, 15, SETBIT);
181
182 }
183
184
185 void set_startseg(int offset) {
186
187         start_condition();
188         regw_u32(I2C_DR, 0x20, 0, OWRITE); 
189         if(!ack_recv())
190                 cputs("Error: initiating write for start segment \n");
191
192         stop_condition();
193         
194         if(!idle())
195                 cputs("Error: timeout");
196
197         start_condition();
198         regw_u32(I2C_DR, 0x03, 0, OWRITE); 
199         if(!ack_recv())
200                 cputs("Error: Can't set start segment \n");
201
202         stop_condition();
203         regw_u32(I2C_CR1, 0x1, 15, SETBIT);
204
205 }
206
207
208 void tm1637_start() {
209
210 unsigned char display_number[10] = {0x00, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFF, 0xF6};
211 //      regw_u32(I2C_CR1, 0x1, 8, SETBIT);
212 //      uint32_t read_status = *I2C_SR1;
213
214 //      regw_u32(I2C_DR, DATASET, 0, OWRITE); 
215         // conform DATA
216 //      read_status = *I2C_SR1;
217 //      read_status = *I2C_SR2;
218
219
220
221 //      start_condition();
222 //      //uint32_t statusr = *I2C_SR1; // clear start_signal
223 //      regw_u32(I2C_DR, 0x20, 0, OWRITE); // write to address CMD
224 //      if(!ack_recv())
225 //              cputs("TIMEOUT!");
226 //      //statusr = *I2C_SR1;
227 //      //statusr = *I2C_SR2;
228 //      stop_condition();
229 //
230 //      //delay();
231
232         set_startseg(0);
233
234         if(!idle())
235                 cputs("Error: timeout");
236
237         tm1637_reset();
238
239 //      start_condition();
240 //      regw_u32(I2C_DR, 0x20, 0, OWRITE); 
241 //      if(!ack_recv())
242 //              cputs("Error: initiating write command\n");
243 //
244 //      stop_condition();
245 //
246 //              if(!idle())
247 //              cputs("Error: timeout");
248
249         start_condition();
250 //      regw_u32(I2C_DR, 0xF0, 0, OWRITE); // dummy header F0 ignored! any value will do as long as last bit is not set
251 //      if(!ack10_recv())
252 //              cputs("Error: dummy addr-10 header not acknowledged\n");
253         regw_u32(I2C_DR, display_number[6], 0, OWRITE); // use ack10 if higher
254         if(!ack10_recv())
255                 cputs("Error: can't set location\n");
256 //      regw_u32(I2C_DR, 0xF4, 0, OWRITE);
257 //      if(!buf_empty())
258 //              cputs("Error: can't write\n");
259 //      regw_u32(I2C_DR, 0x08, 0, OWRITE);
260 //      if(!buf_empty()) 
261 //              cputs("Error: can't write\n");
262 //      regw_u32(I2C_DR, 0x08, 0, OWRITE);
263 //      if(!buf_empty()) 
264 //              cputs("Error: can't write\n");
265         stop_condition(); 
266
267
268
269
270         regw_u32(I2C_CR1, 0x1, 15, SETBIT);
271         /*
272         regw_u32(I2C_DR, 0x00, 0, OWRITE); // ? dummy address
273         if(!ack_recv())
274                 cputs("TIMEOUTA");
275         regw_u32(I2C_DR, 0x03, 0, OWRITE);
276         if(!buf_empty())
277                 cputs("TIMEOUT2A");
278         regw_u32(I2C_DR, 0xFF, 0, OWRITE);
279         if(!buf_empty())
280                 cputs("TIMEOUT2B"); */
281 //
282                 if(!idle())
283                 cputs("Error: timeout");
284
285
286         tm1637_reset();
287
288         set_brightness(0x00);
289         
290
291 /*      delay();
292
293         start_condition();
294         statusr = *I2C_SR1;
295         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
296         if(!ack_recv())
297                 cputs("TIMEOUT4!");
298         stop_condition(); */
299
300
301         /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
302         uint32_t read_status = *I2C_SR1; 
303         regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
304         read_status = *I2C_SR1;
305         read_status = *I2C_SR2;
306         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
307         read_status = *I2C_SR1;
308
309         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
310         read_status = *I2C_SR1;
311         regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
312         read_status = *I2C_SR1;
313         read_status = *I2C_SR2;
314         regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
315
316         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
317         read_status = *I2C_SR1;
318
319         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
320         read_status = *I2C_SR1;
321
322         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
323         read_status = *I2C_SR1;
324         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
325
326 }
327
328 void tm1637_stop() {
329
330         //regw_u32(I2C_CR1, 0x0, 9, SETBIT);
331 }
332
333
334