1 | #include "i2c.h"
|
2 | #include "type.h"
|
3 |
|
4 | //////////////////////////////////////////////////////////////////////////
|
5 | void init_i2c (void)
|
6 | {
|
7 | // I2C Disable
|
8 | LPC_I2C2->I2CONCLR |= (1<<6);
|
9 |
|
10 |
|
11 | // CPU Taktteiler fuer I2C1
|
12 | //PCLKSEL1_bit.PCLK_I2C1 = 0; // CCLK/4
|
13 | LPC_SC->PCLKSEL1 |= (1<<20); // CCLK/1
|
14 | //PCLKSEL1_bit.PCLK_I2C1 = 2; // CCLK/2
|
15 | //PCLKSEL1_bit.PCLK_I2C1 = 3; // CCLK/8
|
16 |
|
17 | LPC_SC->PCONP |= (1 << 26);
|
18 |
|
19 | LPC_PINCON->PINSEL0 |= (1 << 21) | (1 << 23); //Select SDA2 and SCL2 on PIN P0.10 and P0.11
|
20 |
|
21 | LPC_PINCON->PINMODE0 |= (1 << 21) | (1 << 23);
|
22 |
|
23 | LPC_PINCON->PINMODE_OD0 |= (1 << 10);
|
24 | LPC_PINCON->PINMODE_OD0 |= (1 << 11);
|
25 |
|
26 | // I2C Takt
|
27 | // I2C Frequenz = PCLK_I2C / (I2C_I2SCLH + I2C_I2SCLL)
|
28 | // Register Wert ist Anzahl von Taktzyklen fuer high- oder low-Time
|
29 | LPC_I2C2->I2SCLH = 255/2; // High-Time
|
30 | LPC_I2C2->I2SCLL = 255/2; // Low-Time
|
31 |
|
32 | // I2C Configuration Register
|
33 | LPC_I2C2->I2CONCLR |= (1<<2); // ACK Flag Clear AAC
|
34 | LPC_I2C2->I2CONCLR |= (1<<3); // Interrupt Flag Clear SIC
|
35 | LPC_I2C2->I2CONCLR |= (1<<5); // Start Flag Clear STAC
|
36 |
|
37 | LPC_I2C2->I2CONSET |= (1<<6); // I2C Enable I2EN
|
38 | }
|
39 | ///////////////////////////////////////////////////////////////////////////
|
40 |
|
41 | ///////////////////////////////////////////////////////////////////////////
|
42 | unsigned char write_i2c (unsigned char addr, unsigned char *data, unsigned char data_cnt)
|
43 | {
|
44 | unsigned char i;
|
45 | // Start ausgeben
|
46 | LPC_I2C2->I2CONSET |= (1<<5); //STA = 1
|
47 |
|
48 | // Auf Interrupt warten (Start fertig)
|
49 | while (!((LPC_I2C2->I2CONSET >> 3) & 0x01));
|
50 | if (LPC_I2C2->I2STAT != 0x08) return 11;//FALSE;
|
51 |
|
52 | // Adresse ausgeben
|
53 | LPC_I2C2->I2DAT = addr<<1; // Write = 8. Bit low
|
54 | // Start ruecksetzen
|
55 | LPC_I2C2->I2CONCLR |= (1 << 5); //Start zurücksetzen
|
56 | LPC_I2C2->I2CONCLR |= (1 << 3); //Interrupt zurücksetzen
|
57 |
|
58 |
|
59 | // Auf Interrupt warten (ACK Adresse + Write)
|
60 | // Hier bleibt der Controller hängen!!!
|
61 | while (!((LPC_I2C2->I2CONSET >> 3) & 0x01));
|
62 | if (LPC_I2C2->I2STAT != 0x18) return 22;//FALSE;
|
63 |
|
64 | for (i = 0; i < data_cnt; i++)
|
65 | {
|
66 | // Daten ausgeben
|
67 | LPC_I2C2->I2DAT = data[i];
|
68 | // Interrupt ruecksetzen
|
69 | LPC_I2C2->I2CONCLR |= (1 << 3);
|
70 |
|
71 | // Auf Interrupt warten (TX fertig + ACK)
|
72 | while (!((LPC_I2C2->I2CONSET >> 3) & 0x01));
|
73 | if (((LPC_I2C2->I2STAT >> 2) & 0x1F) != 0x28) return 33;//FALSE;
|
74 | }
|
75 |
|
76 | //I2C1CONCLR_bit.SIC = 1; // Interrupt ruecksetzen
|
77 | LPC_I2C2->I2CONCLR |= (1 << 3);
|
78 |
|
79 | // Stop ausgeben
|
80 | LPC_I2C2->I2CONSET |= (1 << 4);
|
81 |
|
82 | return TRUE;
|
83 | }
|
84 | ///////////////////////////////////////////////////////////////////////////
|