eeprom at24c signs of life
[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
30
31 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
32 GPIOs must be configured as open-drain. So, you have to add two additional resistors to
33 pull-up I2C lines. Something between 4K and 10K is a proven value.
34 */
35
36 void at24c_init() {
37
38  /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
39  Configure the clock control registers CCR
40  Configure the rise time register TRIS
41  Program the I2C_CR1 register to enable the peripheral
42
43  ENABLE GPIOB6 and B7*/
44
45  rsetbit(RCC_APB1ENR, 21);
46  rsetbit(RCC_APB2ENR, 3);
47  // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
48  
49  rwrite(GPIOB_CRL, 0xEE444444);
50
51  rsetbitsfrom(I2C_CR2, 0, 0x2); // 36 MHz 
52  rwrite(I2C_TRISE, 0x3); // MAX = 1000ns, TPCLK1 = 500ns (+1)
53  rwrite(I2C_CCR, 0x000A); // standard modeļ¼Œ output 100 kHz (100hz* / perip)
54
55  rsetbit(I2C_CR1, 10); // send ack if receive
56
57  rsetbit(I2C_CR1, 0); // enable
58
59 }
60
61 static void start_condition() {
62
63         rsetbit(I2C_CR1, 8); //start
64
65 }
66
67 static void stop_condition() {
68
69         rsetbit(I2C_CR1, 9); //stop
70 }
71
72 static int ack_recv() {
73
74         int cnt = 0;
75         while(!(*I2C_SR1 & 0x2)) {
76                 cnt++;
77                 if (cnt > TIMEOUT)
78                         return 0;
79         }
80
81         int a = *I2C_SR2;
82         return 1;
83
84 }
85
86 static int buf_empty() {
87         int cnt = 0;
88         while(!(*I2C_SR1 & 0x80)) {
89                 cnt++;
90                 if (cnt > TIMEOUT)
91                         return 0;
92         }
93
94         return 1;
95 }
96
97 static void data_recv() {
98         //int cnt = 0;
99         while(!(*I2C_SR1 & 0x4)) {
100         ///     cnt++;
101         //      if (cnt > TIMEOUT)
102         //              return 0;
103         }
104         //return 1;
105 }
106
107 static int delay() {
108
109         int a = 0;
110         for (int i = 0; i < 0xFFFF; i++)
111                 a++;
112 }
113
114 void at24c_run() {
115
116 //      regw_u32(I2C_CR1, 0x1, 8, SETBIT);
117 //      uint32_t read_status = *I2C_SR1;
118
119 //      regw_u32(I2C_DR, DATASET, 0, OWRITE); 
120         // conform DATA
121 //      read_status = *I2C_SR1;
122 //      read_status = *I2C_SR2;
123
124         uint32_t statusr;
125
126         start_condition();
127         //uint32_t statusr = *I2C_SR1; // clear start_signal
128         rwrite(I2C_DR, 0xA0); // write to address CMD
129         if(!ack_recv())
130                 cputs("CAN'T REACH DEVICE");
131
132         rwrite(I2C_DR, 0x00);
133         if(!buf_empty())
134                 cputs("FAIL");
135         rwrite(I2C_DR, 0x00);
136         if(!buf_empty()) 
137                 cputs("FAIL");
138         //rwrite(I2C_DR, 0x61);
139         //if(!buf_empty())
140         //      cputs("FAIL");
141
142         //statusr = *I2C_SR1;
143         //statusr = *I2C_SR2;
144         stop_condition();
145
146 //      start_condition();
147 //      rwrite(I2C_DR, 0xA0); // dummy write
148 //      if(!ack_recv())
149 //              cputs("CAN'T REACH DEVICE");
150 //
151 //      rwrite(I2C_DR, 0x00);
152 //      if(!buf_empty())
153 //              cputs("FAIL");
154 //      rwrite(I2C_DR, 0x00);
155 //      if(!buf_empty()) 
156 //              cputs("FAIL");
157 //
158         delay();
159
160         start_condition(); // restart condition
161         rwrite(I2C_DR, 0xA1); // read? to address CMD
162         if(!ack_recv())
163                 cputs("COULDN'T START READ CMD");
164
165
166         data_recv();
167                 //cputs("NO RESPONSE");
168
169         char a = (char) *I2C_DR;
170         printf("DATA %c\n", a); 
171
172         stop_condition();
173         //delay();
174
175         //start_condition();
176         //statusr = *I2C_SR1; // clear start_signal
177         //regw_u32(I2C_DR, 0xC1, 0, OWRITE);
178         //if(!ack_recv())
179         //      cputs("TIMEOUT2!");
180         //statusr = *I2C_SR1;
181         //statusr = *I2C_SR2;
182         //regw_u32(I2C_DR, 0x7D, 0, OWRITE);
183         //if(!buf_empty())
184         //      cputs("TIMEOUT3!");
185         //stop_condition();
186
187 /*      delay();
188
189         start_condition();
190         statusr = *I2C_SR1;
191         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
192         if(!ack_recv())
193                 cputs("TIMEOUT4!");
194         stop_condition(); */
195
196
197         /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
198         uint32_t read_status = *I2C_SR1; 
199         regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
200         read_status = *I2C_SR1;
201         read_status = *I2C_SR2;
202         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
203         read_status = *I2C_SR1;
204
205         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
206         read_status = *I2C_SR1;
207         regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
208         read_status = *I2C_SR1;
209         read_status = *I2C_SR2;
210         regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
211
212         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
213         read_status = *I2C_SR1;
214
215         regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
216         read_status = *I2C_SR1;
217
218         regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
219         read_status = *I2C_SR1;
220         regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
221
222 }
223
224