]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp/lib/rpp/src/sys/ti_drv_i2c.c
3118b9e9c6dcdd1868ff6ecbbec80e22092d1f0f
[pes-rpp/rpp-test-sw.git] / rpp / lib / rpp / src / sys / ti_drv_i2c.c
1 /** @file i2c.c
2 *   @brief I2C Driver Implementation File
3 *   @date 10.March.2012
4 *   @version 03.01.00
5 *
6 */
7
8 /* (c) Texas Instruments 2009-2012, All rights reserved. */
9
10 /* USER CODE BEGIN (0) */
11 /* USER CODE END */
12
13 #include "sys/ti_drv_i2c.h"
14
15 /* USER CODE BEGIN (1) */
16 /* USER CODE END */
17
18 /** @struct g_I2CTransfer
19 *   @brief Interrupt mode globals
20 *
21 */
22 struct g_i2cTransfer
23 {
24     uint32_t  mode;
25     uint32_t  length;
26     uint8_t   *data;
27 } g_i2cTransfer[2];
28
29 /* USER CODE BEGIN (2) */
30 /* USER CODE END */
31
32 /** @fn void i2cInit(void)
33 *   @brief Initializes the i2c Driver
34 *
35 *   This function initializes the i2c module.
36 */
37 void i2cInit(void)
38 {
39 /* USER CODE BEGIN (3) */
40 /* USER CODE END */
41
42     /** @b intialize @b I2C */
43
44     /** - i2c out of reset */
45     i2cREG1->MDR = (1 << 5);
46
47     /** - set i2c mode */
48     i2cREG1->MDR =   (0 << 15)     /* nack mode                        */
49                    | (0 << 14)     /* free running                      */
50                    |  0     /* start condtion - master mode only */
51                    | (1 <<11)     /* stop condtion                     */
52                    | (1 <<10)     /* Master/Slave mode                 */
53                    | (I2C_TRANSMITTER)     /* Transmitter/receiver              */
54                    | (I2C_7BIT_AMODE)     /* xpanded address                   */
55                    | (0 << 7)     /* repeat mode                       */
56                    | (0 << 6)     /* digital loopback                  */
57                    | (0 << 4)     /* start byte - master only          */
58                    | (0)     /* free data format                  */
59                    | I2C_8_BIT;     /* bit count                         */
60
61
62     /** - set i2c extended mode */
63     i2cREG1->EMDR = (0 << 25);
64
65     /** - set i2c data count */
66     i2cREG1->CNT = 3;
67
68     /** - disable all interrupts */
69     i2cREG1->IMR = 0x00U;
70
71     /** - set prescale */
72     i2cREG1->PSC = 9;
73
74     /** - set clock rate */
75     i2cREG1->CLKH = 35;
76     i2cREG1->CLKL = 35;
77
78     /** - set i2c pins functional mode */
79     i2cREG1->FUN = (0 );
80
81     /** - set i2c pins default output value */
82     i2cREG1->DOUT = (0 << 1)     /* sda pin */
83                   | (0);     /* scl pin */
84
85     /** - set i2c pins output direction */
86     i2cREG1->DIR = (1 << 1)     /* sda pin */
87                  | (1);     /* scl pin */
88
89     /** - set i2c pins open drain enable */
90     i2cREG1->ODR = (0 << 1)     /* sda pin */
91                  | (0);     /* scl pin */
92
93     /** - set i2c pins pullup/pulldown enable */
94     i2cREG1->PD = (0 << 1)     /* sda pin */
95                 | (0);     /* scl pin */
96
97     /** - set i2c pins pullup/pulldown select */
98     i2cREG1->PSL = (1 << 1)     /* sda pin */
99                  | (1);     /* scl pin */
100
101     /** - set interrupt enable */
102     i2cREG1->IMR    = (0 << 6)     /* Address as slave interrupt      */
103                     | (0 << 5)     /* Stop Condition detect interrupt */
104                     | (1 << 4)     /* Transmit data ready interrupt   */
105                     | (1 << 3)     /* Receive data ready interrupt    */
106                     | (0 << 2)     /* Register Access ready interrupt */
107                     | (0 << 1)     /* No Acknowledgement interrupt    */
108                     | (1);     /* Arbitration Lost interrupt      */
109
110     i2cREG1->MDR |= I2C_RESET_OUT; /* i2c out of reset */
111
112     /** - inialise global transfer variables */
113     g_i2cTransfer[0].mode   = 1 << 8;
114     g_i2cTransfer[0].length = 0;
115
116 /* USER CODE BEGIN (4) */
117 /* USER CODE END */
118
119 }
120
121 /** @fn void i2cSetOwnAdd(i2cBASE_t *i2c, uint32_t oadd)
122 *   @brief Set I2C Own Address
123 *   @param[in] oadd - I2C Own address (7-bit or 10 -bit address)
124 *   @param[in] i2c  - i2c module base address
125 *   Set the Own address of the I2C module.
126 */
127 void i2cSetOwnAdd(i2cBASE_t *i2c, uint32_t oadd)
128 {
129     i2cREG1->OAR = oadd;  /* set own address */
130 }
131
132 /** @fn void i2cSetSlaveAdd(i2cBASE_t *i2c, uint32_t sadd)
133 *   @brief Set Port Direction
134 *   @param[in] sadd - I2C Slave address
135 *   @param[in] i2c  - i2c module base address
136 *   Set the Slave address to communicate which is must in Master mode.
137 */
138 void i2cSetSlaveAdd(i2cBASE_t *i2c, uint32_t sadd)
139 {
140     i2cREG1->SAR = sadd;  /* set slave address */
141 }
142
143 /** @fn void i2cSetBaudrate(i2cBASE_t *i2c, uint32_t baud)
144 *   @brief Change baudrate at runtime.
145 *   @param[in] i2c  - i2c module base address
146 *   @param[in] baud - baudrate in KHz
147 *
148 *   Change the i2c baudrate at runtime.
149 */
150 void i2cSetBaudrate(i2cBASE_t *i2c, uint32_t baud)
151 {
152     uint32_t prescale;
153     uint32_t d;
154     uint32_t ck;
155     double   vclk = 80.000 * 1000000.0;
156
157 /* USER CODE BEGIN (5) */
158 /* USER CODE END */
159     prescale = (uint32_t) ((vclk /8000000) - 1);
160
161     if(prescale>=2)
162     {
163     d = 5;
164     }
165     else
166     {
167     d = prescale ? 6 : 7;
168     }
169
170     ck = ((vclk)/(2*baud*1000*(prescale+1)))-d;
171
172     i2cREG1->PSC  = prescale;
173     i2cREG1->CLKH = ck;
174     i2cREG1->CLKL = ck;
175
176 /* USER CODE BEGIN (6) */
177 /* USER CODE END */
178
179 }
180
181 /** @fn void i2cSetStart(i2cBASE_t *i2c)
182 *   @brief Set i2c start condition
183 *   @param[in] i2c  - i2c module base address
184 *   Set i2c to generate a start bit (Only in Master mode)
185 */
186 void i2cSetStart(i2cBASE_t *i2c)
187 {
188 /* USER CODE BEGIN (7) */
189 /* USER CODE END */
190
191     i2cREG1->MDR |= I2C_START_COND;  /* set start condition */
192
193 /* USER CODE BEGIN (8) */
194 /* USER CODE END */
195 }
196
197 /** @fn void i2cSetStop(i2cBASE_t *i2c)
198 *   @brief Set i2c stop condition
199 *   @param[in] i2c  - i2c module base address
200 *   Set i2c to generate a stop bit (Only in Master mode)
201 */
202 void i2cSetStop(i2cBASE_t *i2c)
203 {
204 /* USER CODE BEGIN (9) */
205 /* USER CODE END */
206
207     i2cREG1->MDR |= I2C_STOP_COND;  /* generate stop condition */
208
209 /* USER CODE BEGIN (10) */
210 /* USER CODE END */
211 }
212
213 /** @fn void i2cSetCount(i2cBASE_t *i2c,uint32_t cnt)
214 *   @brief Set i2c data count
215 *   @param[in] i2c  - i2c module base address
216 *   @param[in] cnt  - data count
217 *   Set i2c count to a transfer value after which the stop condition needs to be generated.
218 *   (Only in Master Mode)
219 */
220 void i2cSetCount(i2cBASE_t *i2c ,uint32_t cnt)
221 {
222 /* USER CODE BEGIN (11) */
223 /* USER CODE END */
224
225     i2cREG1->CNT = cnt;  /* set i2c count  */
226
227 /* USER CODE BEGIN (12) */
228 /* USER CODE END */
229 }
230
231 /** @fn uint32_t i2cIsTxReady(i2cBASE_t *i2c)
232 *   @brief Check if Tx buffer empty
233 *   @param[in] i2c - i2c module base address
234 *
235 *   @return The TX ready flag
236 *
237 *   Checks to see if the Tx buffer ready flag is set, returns
238 *   0 is flags not set otherwise will return the Tx flag itself.
239 */
240 uint32_t i2cIsTxReady(i2cBASE_t *i2c)
241 {
242 /* USER CODE BEGIN (13) */
243 /* USER CODE END */
244
245     return i2cREG1->STR & I2C_TX_INT;
246
247 /* USER CODE BEGIN (14) */
248 /* USER CODE END */
249 }
250
251 /** @fn void i2cSendByte(i2cBASE_t *i2c, uint8_t byte)
252 *   @brief Send Byte
253 *   @param[in] i2c  - i2c module base address
254 *   @param[in] byte - byte to transfer
255 *
256 *   Sends a single byte in polling mode, will wait in the
257 *   routine until the transmit buffer is empty before sending
258 *   the byte.  Use i2cIsTxReady to check for Tx buffer empty
259 *   before calling i2cSendByte to avoid waiting.
260 */
261 void i2cSendByte(i2cBASE_t *i2c, uint8_t byte)
262 {
263 /* USER CODE BEGIN (15) */
264 /* USER CODE END */
265
266     while ((i2cREG1->STR & I2C_TX_INT) == 0) { /* wait */ };
267     i2cREG1->DXR = byte;
268
269 /* USER CODE BEGIN (16) */
270 /* USER CODE END */
271 }
272
273 /** @fn void i2cSend(i2cBASE_t *i2c, uint32_t length, uint8_t *data)
274 *   @brief Send Data
275 *   @param[in] i2c    - i2c module base address
276 *   @param[in] length - number of data words to transfer
277 *   @param[in] data   - pointer to data to send
278 *
279 *   Send a block of data pointed to by 'data' and 'length' bytes
280 *   long.  If interrupts have been enabled the data is sent using
281 *   interrupt mode, otherwise polling mode is used.  In interrupt
282 *   mode transmition of the first byte is started and the routine
283 *   returns imediatly, i2cSend must not be called again until the
284 *   transfer is complete, when the i2cNotification callback will
285 *   be called.  In polling mode, i2cSend will not return  until
286 *   the transfer is complete.
287 *
288 *   @note if data word is less than 8 bits, then the data must be left
289 *         aligned in the data byte.
290 */
291 void i2cSend(i2cBASE_t *i2c, uint32_t length, uint8_t *data)
292 {
293     uint32_t index = i2c == i2cREG1 ? 0 : 1;
294
295 /* USER CODE BEGIN (17) */
296 /* USER CODE END */
297
298     if ((g_i2cTransfer[index].mode & I2C_TX_INT) != 0)
299     {
300         /* we are in interrupt mode */
301
302         g_i2cTransfer[index].length = length;
303         g_i2cTransfer[index].data   = data;
304
305         /* start transmit by sending first byte */
306         i2cREG1->DXR = *g_i2cTransfer[index].data++;
307         i2cREG1->IMR = I2C_TX_INT;
308     }
309     else
310     {
311         /* send the data */
312         while (length-- > 0)
313         {
314             while ((i2cREG1->STR & I2C_TX_INT) == 0) { /* wait */ };
315             i2cREG1->DXR = *data++;
316         }
317     }
318 /* USER CODE BEGIN (18) */
319 /* USER CODE END */
320 }
321
322 /** @fn uint32_t i2cIsRxReady(i2cBASE_t *i2c)
323 *   @brief Check if Rx buffer full
324 *   @param[in] i2c - i2c module base address
325 *
326 *   @return The Rx ready flag
327 *
328 *   Checks to see if the Rx buffer full flag is set, returns
329 *   0 is flags not set otherwise will return the Rx flag itself.
330 */
331 uint32_t i2cIsRxReady(i2cBASE_t *i2c)
332 {
333 /* USER CODE BEGIN (19) */
334 /* USER CODE END */
335
336     return i2cREG1->STR & I2C_RX_INT;
337
338 /* USER CODE BEGIN (20) */
339 /* USER CODE END */
340 }
341
342
343 /** @fn uint32_t i2cRxError(i2cBASE_t *i2c)
344 *   @brief Return Rx Error flags
345 *   @param[in] i2c - i2c module base address
346 *
347 *   @return The Rx error flags
348 *
349 *   Returns the Rx framing, overun and parity errors flags,
350 *   also clears the error flags before returning.
351 */
352 uint32_t i2cRxError(i2cBASE_t *i2c)
353 {
354     uint32_t status = i2cREG1->STR & (I2C_AL_INT | I2C_NACK_INT);
355
356 /* USER CODE BEGIN (21) */
357 /* USER CODE END */
358
359     i2cREG1->STR = I2C_AL_INT | I2C_NACK_INT;
360
361 /* USER CODE BEGIN (22) */
362 /* USER CODE END */
363
364     return status;
365
366 }
367
368 /** @fn void i2cClearSCD(i2cBASE_t *i2c)
369 *   @brief Clears the Stop condition detect flags.
370 *   @param[in] i2c - i2c module base address
371 *
372 *   This sunction is called to clear the Stop condition detect(SCD) flag
373 */
374 void i2cClearSCD(i2cBASE_t *i2c)
375 {
376 /* USER CODE BEGIN (23) */
377 /* USER CODE END */
378
379     i2cREG1->STR = I2C_SCD_INT;
380
381 /* USER CODE BEGIN (24) */
382 /* USER CODE END */
383 }
384
385 /** @fn uint32_t i2cReceiveByte(i2cBASE_t *i2c)
386 *   @brief Receive Byte
387 *   @param[in] i2c - i2c module base address
388 *
389 *   @return Received byte
390 *
391 *    Recieves a single byte in polling mode.  If there is
392 *    not a byte in the receive buffer the routine will wait
393 *    until one is received.   Use i2cIsRxReady to check to
394 *    see if the buffer is full to avoid waiting.
395 */
396 uint32_t i2cReceiveByte(i2cBASE_t *i2c)
397 {
398     while ((i2cREG1->STR & I2C_RX_INT) == 0) { /* wait */ };
399
400 /* USER CODE BEGIN (25) */
401 /* USER CODE END */
402
403     return i2cREG1->DRR;
404 }
405
406 /** @fn void i2cReceive(i2cBASE_t *i2c, uint32_t length, uint8_t *data)
407 *   @brief Receive Data
408 *   @param[in] i2c    - i2c module base address
409 *   @param[in] length - number of data words to transfer
410 *   @param[in] data   - pointer to data buffer
411 *
412 *   Receive a block of 'length' bytes long and place it into the
413 *   data buffer pointed to by 'data'.  If interrupts have been
414 *   enabled the data is received using interrupt mode, otherwise
415 *   polling mode is used.  In interrupt mode receive is setup and
416 *   the routine returns imediatly, i2cReceive must not be called
417 *   again until the transfer is complete, when the i2cNotification
418 *   callback will be called.  In polling mode, i2cReceive will not
419 *   return  until the transfer is complete.
420 */
421 void i2cReceive(i2cBASE_t *i2c, uint32_t length, uint8_t *data)
422 {
423
424 /* USER CODE BEGIN (26) */
425 /* USER CODE END */
426     if ((i2cREG1->IMR & I2C_RX_INT) != 0)
427     {
428         /* we are in interrupt mode */
429         uint32_t index = i2c == i2cREG1 ? 0 : 1;
430
431         /* clear error flags */
432         i2cREG1->STR = I2C_AL_INT | I2C_NACK_INT;
433
434         g_i2cTransfer[index].length = length;
435         g_i2cTransfer[index].data   = data;
436     }
437     else
438     {
439         while (length-- > 0)
440         {
441             while ((i2cREG1->STR & I2C_RX_INT) == 0) { /* wait */ };
442             *data++ = i2cREG1->DRR;
443         }
444     }
445
446 /* USER CODE BEGIN (27) */
447 /* USER CODE END */
448 }
449
450 /** @fn void i2cEnableLoopback(i2cBASE_t *i2c)
451 *   @brief Enable Loopback mode for self test
452 *   @param[in] i2c        - i2c module base address
453 *
454 *   This function enables the Loopback mode for self test.
455 */
456 void i2cEnableLoopback(i2cBASE_t *i2c)
457 {
458 /* USER CODE BEGIN (28) */
459 /* USER CODE END */
460
461     /* enable digital loopback    */
462     i2cREG1->MDR |= (1 << 6);
463
464 /* USER CODE BEGIN (29) */
465 /* USER CODE END */
466 }
467
468 /** @fn void i2cDisableLoopback(i2cBASE_t *i2c)
469 *   @brief Enable Loopback mode for self test
470 *   @param[in] i2c        - i2c module base address
471 *
472 *   This function disable the Loopback mode.
473 */
474 void i2cDisableLoopback(i2cBASE_t *i2c)
475 {
476 /* USER CODE BEGIN (30) */
477 /* USER CODE END */
478
479     /* Disable Loopback Mode */
480     i2cREG1->MDR &= 0xFFFFFFBF;
481
482 /* USER CODE BEGIN (31) */
483 /* USER CODE END */
484 }
485
486 /** @fn i2cEnableNotification(i2cBASE_t *i2c, uint32_t flags)
487 *   @brief Enable interrupts
488 *   @param[in] i2c   - i2c module base address
489 *   @param[in] flags - Interrupts to be enabled, can be ored value of:
490 *                      i2c_FE_INT    - framming error,
491 *                      i2c_OE_INT    - overrun error,
492 *                      i2c_PE_INT    - parity error,
493 *                      i2c_RX_INT    - receive buffer ready,
494 *                      i2c_TX_INT    - transmit buffer ready,
495 *                      i2c_WAKE_INT  - wakeup,
496 *                      i2c_BREAK_INT - break detect
497 */
498 void i2cEnableNotification(i2cBASE_t *i2c, uint32_t flags)
499 {
500     uint32_t index = i2c == i2cREG1 ? 0 : 1;
501
502 /* USER CODE BEGIN (32) */
503 /* USER CODE END */
504
505     g_i2cTransfer[index].mode |= (flags & I2C_TX_INT);
506     i2cREG1->IMR               = (flags & ~I2C_TX_INT);
507 }
508
509 /** @fn i2cDisableNotification(i2cBASE_t *i2c, uint32_t flags)
510 *   @brief Disable interrupts
511 *   @param[in] i2c   - i2c module base address
512 *   @param[in] flags - Interrupts to be disabled, can be ored value of:
513 *                      i2c_FE_INT    - framming error,
514 *                      i2c_OE_INT    - overrun error,
515 *                      i2c_PE_INT    - parity error,
516 *                      i2c_RX_INT    - receive buffer ready,
517 *                      i2c_TX_INT    - transmit buffer ready,
518 *                      i2c_WAKE_INT  - wakeup,
519 *                      i2c_BREAK_INT - break detect
520 */
521 void i2cDisableNotification(i2cBASE_t *i2c, uint32_t flags)
522 {
523     uint32_t index = i2c == i2cREG1 ? 0 : 1;
524
525 /* USER CODE BEGIN (33) */
526 /* USER CODE END */
527
528     g_i2cTransfer[index].mode &= ~(flags & I2C_TX_INT);
529     i2cREG1->IMR               = (flags & ~I2C_TX_INT);
530 }
531
532 /** @fn void i2cInterrupt(void)
533 *   @brief Interrupt for I2C
534 */
535 #pragma INTERRUPT(i2cInterrupt, IRQ)
536
537 void i2cInterrupt(void)
538 {
539     uint32_t vec = (i2cREG1->IVR & 0x00000007);
540
541 /* USER CODE BEGIN (34) */
542 /* USER CODE END */
543
544     switch (vec)
545     {
546     case 1:
547 /* USER CODE BEGIN (35) */
548 /* USER CODE END */
549         i2cNotification(i2cREG1, I2C_AL_INT);
550         break;
551     case 2:
552 /* USER CODE BEGIN (36) */
553 /* USER CODE END */
554         i2cNotification(i2cREG1, I2C_NACK_INT);
555         break;
556     case 3:
557 /* USER CODE BEGIN (37) */
558 /* USER CODE END */
559         i2cNotification(i2cREG1, I2C_ARDY_INT);
560         break;
561     case 4:
562 /* USER CODE BEGIN (38) */
563 /* USER CODE END */
564         /* receive */
565         {   uint32_t byte = i2cREG1->DRR;
566
567             if (g_i2cTransfer[0].length > 0)
568             {
569                 *g_i2cTransfer[0].data++ = byte;
570                 g_i2cTransfer[0].length--;
571                 if (g_i2cTransfer[0].length == 0)
572                 {
573                     i2cNotification(i2cREG1, I2C_RX_INT);
574                 }
575             }
576         }
577         break;
578     case 5:
579 /* USER CODE BEGIN (39) */
580 /* USER CODE END */
581         /* transmit */
582         if (--g_i2cTransfer[0].length > 0)
583         {
584             i2cREG1->DXR = *g_i2cTransfer[0].data++;
585         }
586         else
587         {
588             i2cREG1->STR = I2C_TX_INT;
589             i2cNotification(i2cREG1, I2C_TX_INT);
590         }
591         break;
592
593
594     case 6:
595 /* USER CODE BEGIN (40) */
596 /* USER CODE END */
597         /* transmit */
598         i2cNotification(i2cREG1, I2C_SCD_INT);
599         break;
600
601     case 7:
602 /* USER CODE BEGIN (41) */
603 /* USER CODE END */
604         i2cNotification(i2cREG1, I2C_AAS_INT);
605         break;
606
607     default:
608 /* USER CODE BEGIN (42) */
609 /* USER CODE END */
610         /* phantom interrupt, clear flags and return */
611         i2cREG1->STR = 0x000007FF;
612         break;
613     }
614 /* USER CODE BEGIN (43) */
615 /* USER CODE END */
616 }
617
618