Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
mbed_i2c.c
1#ifdef __FreeRTOS__
2
3#include "i2c_api.h"
4
5#include "os/os.h"
6
7#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
8#define I2CCOUNT 3
9#elif defined(TARGET_LPC11Cxx)
10#define I2CCOUNT 1
11#define i2c0_irq I2C_IRQHandler
12#define INTERRUPT_ATTRIBUTE
13#else
14#error CPU undefined
15#endif
16
17
18os_sem_t i2c_sem[I2CCOUNT];
19
20int i2c_get_id(i2c_t* obj) {
21 switch ((int)obj->i2c) {
22 case I2C_0: return 0;
23#if I2CCOUNT > 1
24 case I2C_1: return 1;
25 case I2C_2: return 2;
26#endif
27 }
28 abort();
29}
30
31void i2c0_irq(void) INTERRUPT_ATTRIBUTE;
32#if I2CCOUNT > 1
33void i2c1_irq(void) INTERRUPT_ATTRIBUTE;
34void i2c2_irq(void) INTERRUPT_ATTRIBUTE;
35#endif
36
37
38static const IRQn_Type i2c_irqn[I2CCOUNT] = {
39#if I2CCOUNT > 1
40 I2C0_IRQn,
41 I2C1_IRQn,
42 I2C2_IRQn
43#else
44 I2C_IRQn,
45#endif
46};
47
48void i2c0_irq(void) {
49 os_sem_post_from_isr(i2c_sem+0);
50 NVIC_DisableIRQ(i2c_irqn[0]);
51#ifdef INTERRUPT_ACK
52 LPC_VIC->Address = 0;
53#endif
54}
55
56#if I2CCOUNT > 1
57void i2c1_irq(void) {
58 os_sem_post_from_isr(i2c_sem+1);
59 NVIC_DisableIRQ(i2c_irqn[1]);
60#ifdef INTERRUPT_ACK
61 LPC_VIC->Address = 0;
62#endif
63}
64
65void i2c2_irq(void) {
66 os_sem_post_from_isr(i2c_sem+2);
67 NVIC_DisableIRQ(i2c_irqn[2]);
68#ifdef INTERRUPT_ACK
69 LPC_VIC->Address = 0;
70#endif
71}
72#endif
73
74static const uint32_t irqptr[I2CCOUNT] = {
75 (uint32_t) &i2c0_irq,
76#if I2CCOUNT > 1
77 (uint32_t) &i2c1_irq,
78 (uint32_t) &i2c2_irq,
79#endif
80};
81
82void i2c_init_irq(i2c_t *obj) {
83 int id = i2c_get_id(obj);
84 os_sem_init(&i2c_sem[id], 0);
85#if I2CCOUNT > 1
86 NVIC_SetVector(i2c_irqn[id], irqptr[id]);
87#endif
88}
89
90int i2c_wait_SI(i2c_t *obj) {
91 static const long long kTimeoutNano = MSEC_TO_NSEC(500);
92 int id = i2c_get_id(obj);
93#ifdef TARGET_LPC11Cxx
94 while (!(obj->i2c->CONSET & (1 << 3))) {
95#else
96 while (!(obj->i2c->I2CONSET & (1 << 3))) {
97#endif
98 NVIC_EnableIRQ(i2c_irqn[id]);
99 if (os_sem_timedwait(i2c_sem + id, kTimeoutNano) < 0) {
100 return -1;
101 }
102 }
103 return 0;
104}
105
106#endif // __FreeRTOS__
#define MSEC_TO_NSEC(_msec)
Convert a millisecond value to a nanosecond value.
Definition os.h:268
OS_INLINE int os_sem_init(os_sem_t *sem, unsigned int value)
Initialize a semaphore.
Definition os.h:604