1 | void I2C_Init(void)
|
2 | {
|
3 | // Configure TWI PIOs
|
4 | AT91F_TWI_CfgPIO ();
|
5 |
|
6 | // Configure PMC by enabling TWI clock
|
7 | AT91F_TWI_CfgPMC ();
|
8 |
|
9 | // Configure TWI in master mode
|
10 | AT91F_TWI_Configure (AT91C_BASE_TWI);
|
11 |
|
12 | // Set TWI Clock Waveform Generator Register
|
13 | I2C_SetClock();
|
14 |
|
15 | //TWI NACK Bug workaround
|
16 | AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
|
17 | AT91C_ID_TWI,
|
18 | 7,
|
19 | AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE,
|
20 | dummy_irq);
|
21 | *AT91C_TWI_IER = (1<<0);
|
22 |
|
23 | *AT91C_TWI_CR = AT91C_TWI_MSEN;
|
24 | }
|
25 |
|
26 | unsigned char I2C_read(unsigned char dev_adr, // slave address
|
27 | unsigned char mem_adr, // internal memory address
|
28 | unsigned char *data, // datapointer for the return data
|
29 | unsigned int n_byte){ // count of bytes to read
|
30 | unsigned int timeout = 0;
|
31 | unsigned char counter;
|
32 | unsigned int uiByteCounter = 0;
|
33 | timeout = 0;
|
34 |
|
35 | *AT91C_TWI_CR = AT91C_TWI_MSEN; //Enable the TWI Master Mode
|
36 | *AT91C_TWI_IADR = mem_adr; //Set the TWI Slave memory address
|
37 | *AT91C_TWI_MMR = ((dev_adr<<16) //Slave address
|
38 | | AT91C_TWI_MREAD); //Master read mode
|
39 | //| AT91C_TWI_IADRSZ_1_BYTE); //Slave internal addtess site 1 byte
|
40 | *AT91C_TWI_CR = AT91C_TWI_START; //Send the start condition slave address and set read mode
|
41 | while(!(*AT91C_AIC_IPR & (1<<AT91C_ID_TWI))) //TX Complete TWI irq polling
|
42 | {
|
43 | timeout++;
|
44 | if(timeout >= 10000000){
|
45 | I2C_stop();
|
46 | return TWI_TXTIMEOUT; //Exit on TXCOMP timeout
|
47 | }
|
48 | }
|
49 | I2C_nack_wait();
|
50 | if(*AT91C_TWI_SR & AT91C_TWI_NACK){ //Slave exist and send ACK?
|
51 | I2C_stop();
|
52 | return TWI_NACK; //Exit on NACK
|
53 | }
|
54 | counter = 0;
|
55 |
|
56 | while(uiByteCounter != n_byte)
|
57 | { //Recive
|
58 | timeout = 0;
|
59 | while((!(*AT91C_TWI_SR & AT91C_TWI_RXRDY))){ //Wait for data redady
|
60 | timeout++;
|
61 | if(timeout>=1000000){
|
62 | I2C_stop();
|
63 | return TWI_TXTIMEOUT_READ; //Exit on RXRDY timeout
|
64 | }
|
65 | }
|
66 | data[uiByteCounter++] = AT91C_BASE_TWI->TWI_RHR;//(unsigned char) *AT91C_TWI_RHR; //Read data
|
67 | uiByteCounter++;
|
68 | }
|
69 |
|
70 | I2C_stop();
|
71 |
|
72 | return 0;
|
73 | }
|
74 |
|
75 | static void dummy_irq(void)
|
76 | {
|
77 | volatile unsigned int uiStatus = 0;
|
78 | volatile unsigned int uiDelay = 0;
|
79 |
|
80 | // signal start of Interrupt Service Routine
|
81 | uiStatus = AT91C_BASE_AIC->AIC_IVR;
|
82 | uiStatus = uiStatus;
|
83 |
|
84 |
|
85 |
|
86 | // signal end of Interrupt Service Routine
|
87 | uiStatus = AT91C_BASE_AIC->AIC_EOICR;
|
88 | uiStatus = uiStatus;
|
89 | }
|
90 |
|
91 | Danke und Gruss
|