eeprom, cases for n=1, n=2 and n>2
[cortex-from-scratch] / drivers / at24c.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  *
9  * */
10
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include <sys/mmap.h>
16 #include <sys/robsys.h>
17
18 #include <lib/regfunc.h>
19 #include <lib/string.h>
20 #include <lib/stdio.h>
21 #include <lib/tinyprintf.h>
22
23 #include <drivers/at24c.h>
24
25 #define TIMEOUT 5000
26
27 #define READ_CMD        0xA1
28 #define WRITE_CMD       0xA0
29 #define PAGE 64 /* Bytes that can be written continiously */
30 #define BUFFER 4 /* */
31
32 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
33 GPIOs must be configured as open-drain. So, you have to add two additional resistors to
34 pull-up I2C lines. Something between 4K and 10K is a proven value. 
35 */
36
37 static char eeprombuf[BUFFER];
38
39 void * cap_handler() {
40
41         printf("a!");
42 }
43
44 void at24c_init() {
45
46  /* Program the peripheral input clock in I2C_CR2 Register
47   *  in order to generate correct timings. Configure the clock control registers CCR
48  Configure the rise time register TRIS  Program the I2C_CR1 register to enable the peripheral Enable GPIOB6 and B7*/
49
50  rsetbit(RCC_APB1ENR, 21);
51  rsetbit(RCC_APB2ENR, 3);
52  rwrite(GPIOB_CRL, 0xEE444444);
53  rsetbitsfrom(I2C_CR2, 0, 0x2); // 2 MHz 
54  rwrite(I2C_TRISE, 0x3); // MAX = 1000ns, TPCLK1 = 500ns (+1)
55  rwrite(I2C_CCR, 0x000A); // standard modeļ¼Œ output 100 kHz (100hz* / perip)
56  rsetbit(I2C_CR1, 10); // send ack if Master receives data
57  rsetbit(I2C_CR2, 10); // buffer interrupt
58  rsetbit(I2C_CR1, 0); // enable
59
60
61 }
62
63 static void start_condition() {
64         rsetbit(I2C_CR1, 8); //start
65 }
66
67 static void stop_condition() {
68         rsetbit(I2C_CR1, 9); //stop
69 }
70
71 static int ack_recv() {
72         int cnt = 0;
73         while(!(*I2C_SR1 & 0x2)) {
74                 cnt++;
75                 if (cnt > TIMEOUT)
76                         return 0;
77         }
78
79         int a = *I2C_SR2;
80         return 1;
81 }
82
83 static int buf_empty() {
84         int cnt = 0;
85         while(!(*I2C_SR1 & 0x80)) {
86                 cnt++;
87                 if (cnt > TIMEOUT)
88                         return 0;
89         }
90         return 1;
91 }
92
93 // TODO: interrupt base, so it doesn't block
94 static void data_recv() {
95         while(!(*I2C_SR1 & 0x40)) {
96         }
97 }
98
99 static void late_recv() {
100         while(!(*I2C_SR1 & 0x4)) {
101         }
102 }
103
104 // TODO: polling
105 static int delay() {
106
107         int a = 0;
108         for (int i = 0; i < 0xFFFF; i++)
109                 a++;
110 }
111
112 int eeprom_write(uint16_t addr, char * data, size_t size) {
113         
114         if(size > PAGE) {
115                 printf("Maximum writable page size: %d\n", PAGE);
116                 return -1;
117         }
118
119         uint8_t hi_lo[] = { (uint8_t)(addr >> 8), (uint8_t)addr }; 
120         
121         start_condition();
122         rwrite(I2C_DR, WRITE_CMD);
123         if(!ack_recv()) {
124                 printf("Can't reach device");
125                 return -1;
126         }
127
128         rwrite(I2C_DR, hi_lo[0]); // higher part of address
129         if(!buf_empty()) {
130                 printf("Can't address location");
131                 return -1;
132         }
133         rwrite(I2C_DR,hi_lo[1]); // lower part of address
134         if(!buf_empty()) {
135                 printf("Can't address location");
136                 return -1;
137         }
138
139         for (int i = 0; i < size; i++) {
140                 rwrite(I2C_DR, *data++);
141                 if(!buf_empty()) {
142                         printf("Write error");
143                         return -1;
144                 }       
145         }
146
147         stop_condition();
148         
149         return 0;
150 }
151 /* Random access read based on dummy write  */
152 int eeprom_read(uint16_t addr, int num) {
153
154         printf("ENTERING");     
155         uint8_t hi_lo[] = { (uint8_t)(addr >> 8), (uint8_t)addr }; 
156
157         /* Dummy write to set address */        
158         start_condition();
159         rwrite(I2C_DR, WRITE_CMD);
160         if(!ack_recv()) {
161                 printf("Can't reach device");
162                 return -1;
163         }
164
165         rwrite(I2C_DR, hi_lo[0]); // higher part of address
166         if(!buf_empty()) {
167                 printf("Can't address location");
168                 return -1;
169         }
170         rwrite(I2C_DR,hi_lo[1]); // lower part of address
171         if(!buf_empty()) {
172                 printf("Can't address location");
173                 return -1;
174         }
175         stop_condition();
176         
177         delay(); // NEEDED?
178
179
180         if (num == 1) {
181                 start_condition(); // restart condition
182                 rwrite(I2C_DR, READ_CMD); // read? to address CMD
183                 if(!ack_recv()) {
184                         printf("Can't initiate read");
185                         return -1;
186                 }
187                 stop_condition();
188                 data_recv();
189                 char c = (char) *I2C_DR;
190                 printf("DATA: %c\n", c);
191         }
192
193         else if (num == 2) {
194                 rsetbit(I2C_CR1, 10); // set ACK
195                 rsetbit(I2C_CR1, 11); // set POS
196                 start_condition(); // restart condition
197                 rwrite(I2C_DR, READ_CMD); // read to address CMD
198                 if(!ack_recv()) {
199                         printf("Can't initiate read");
200                         return -1;
201                 }       
202                 rclrbit(I2C_CR1, 10); // clear ACK
203                 late_recv();
204                 stop_condition();
205                 char c = (char) *I2C_DR;
206                 char c2 = (char) *I2C_DR;
207                 printf("DATA: %c,%c\n", c, c2);
208         }
209
210         else if (num > 2) {
211                 rsetbit(I2C_CR1, 10); // set ACK
212                 start_condition(); // restart condition
213                 rwrite(I2C_DR, READ_CMD); // read to address CMD
214                 if(!ack_recv()) {
215                         printf("Can't initiate read");
216                         return -1;
217                 }       
218                 for(int i = 0; i < num-3; i++) {
219                         data_recv();
220                         eeprombuf[i] = (char) *I2C_DR;
221                 }
222                 late_recv();
223                 rclrbit(I2C_CR1, 10);
224                 eeprombuf[num-3] = *I2C_DR;
225                 stop_condition();
226                 eeprombuf[num-2] = *I2C_DR;
227                 data_recv();
228                 eeprombuf[num-1] = *I2C_DR;
229                 eeprombuf[num] = '\0';
230                 printf("DATA: %s\n", eeprombuf); 
231         }
232
233
234
235 //W     rsetbit(I2C_CR1, 10); // send ack if Master receives data
236 //W//   data_recv();
237 //W//   char c = *I2C_DR;
238 //W//   printf("%d:%p\n", addr, c);
239 //W     for (int i = 0; i < BUFFER ; i++ ) {
240 //W             data_recv();
241 //W             buf[i] = (char) *I2C_DR;
242 //W     }
243 //W
244 //W     printf("%p, %p, %p, %p\n", *I2C_SR1, *I2C_SR2, *I2C_DR, *I2C_CR1);
245 //      printf("DATA: %s\n", buf);
246
247 }
248
249 void at24c_run() {
250
251 //      char * gd = "abcd";
252 //      eeprom_write(0x0000, gd, strlen(gd));
253
254 //      delay();
255 //      char * global_data = "abcdefghijklmnop";
256
257 //      eeprom_write(0x0080, global_data, strlen(global_data));
258         
259 //      delay();
260
261 //      for (int i = 0; i < 0xFFFF; i++) { 
262 //              eeprom_read(i);
263 //              delay();
264 //      }
265
266         //delay();
267
268 //      delay();
269 //      eeprom_read(0x0000, 1);
270 //      delay();
271 //      eeprom_read(0x0000, 2);
272         delay();
273         eeprom_read(0x0000, 4);
274         delay();
275
276 //W     uint32_t statusr;
277 //W
278 //W     start_condition();
279 //W     rwrite(I2C_DR, WRITE_CMD); // write to address CMD
280 //W     if(!ack_recv())
281 //W             cputs("CAN'T REACH DEVICE");
282 //W
283 //W     rwrite(I2C_DR, 0x00);
284 //W     if(!buf_empty())
285 //W             cputs("FAIL");
286 //W     rwrite(I2C_DR, 0x03);
287 //W     if(!buf_empty()) 
288 //W             cputs("FAIL");
289 //W     //rwrite(I2C_DR, 0x61);
290 //W     //if(!buf_empty())
291 //W     //      cputs("FAIL");
292 //W
293 //W     //statusr = *I2C_SR1;
294 //W     //statusr = *I2C_SR2;
295 //W     stop_condition();
296
297 //      start_condition();
298 //      rwrite(I2C_DR, 0xA0); // dummy write
299 //      if(!ack_recv())
300 //              cputs("CAN'T REACH DEVICE");
301 //
302 //      rwrite(I2C_DR, 0x00);
303 //      if(!buf_empty())
304 //              cputs("FAIL");
305 //      rwrite(I2C_DR, 0x00);
306 //      if(!buf_empty()) 
307 //              cputs("FAIL");
308 //
309 //W     delay();
310 //W
311 //W     start_condition(); // restart condition
312 //W     rwrite(I2C_DR, 0xA1); // read? to address CMD
313 //W     if(!ack_recv())
314 //W             cputs("COULDN'T START READ CMD");
315 //W
316 //W
317 //W     data_recv();
318 //W             //cputs("NO RESPONSE");
319 //W
320 //W     char a = (char) *I2C_DR;
321 //W     printf("DATA %c\n", a); 
322 //W
323 //W     stop_condition();
324         //delay();
325
326         //start_condition();
327         //statusr = *I2C_SR1; // clear start_signal
328         //regw_u32(I2C_DR, 0xC1, 0, OWRITE);
329         //if(!ack_recv())
330         //      cputs("TIMEOUT2!");
331         //statusr = *I2C_SR1;
332         //statusr = *I2C_SR2;
333         //regw_u32(I2C_DR, 0x7D, 0, OWRITE);
334         //if(!buf_empty())
335         //      cputs("TIMEOUT3!");
336         //stop_condition();
337
338 /*      delay();
339
340         start_condition();
341         statusr = *I2C_SR1;
342         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
343         if(!ack_recv())
344                 cputs("TIMEOUT4!");
345         stop_condition(); */
346
347
348         /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
349         uint32_t read_status = *I2C_SR1; 
350         regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
351         read_status = *I2C_SR1;
352         read_status = *I2C_SR2;
353         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
354         read_status = *I2C_SR1;
355
356         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
357         read_status = *I2C_SR1;
358         regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
359         read_status = *I2C_SR1;
360         read_status = *I2C_SR2;
361         regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
362
363         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
364         read_status = *I2C_SR1;
365
366         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
367         read_status = *I2C_SR1;
368
369         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
370         read_status = *I2C_SR1;
371         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
372
373 }
374
375