1 | #include <stdio.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | #include "General.h"
|
5 | #include "TWI_Master.h"
|
6 |
|
7 | /****************************************************************************
|
8 | TWI State codes
|
9 | ****************************************************************************/
|
10 | // General TWI Master staus codes
|
11 | #define TWI_START 0x08 // START has been transmitted
|
12 | #define TWI_REP_START 0x10 // Repeated START has been transmitted
|
13 | #define TWI_ARB_LOST 0x38 // Arbitration lost
|
14 |
|
15 | // TWI Master Transmitter staus codes
|
16 | #define TWI_MTX_ADR_ACK 0x18 // SLA+W has been tramsmitted and ACK received
|
17 | #define TWI_MTX_ADR_NACK 0x20 // SLA+W has been tramsmitted and NACK received
|
18 | #define TWI_MTX_DATA_ACK 0x28 // Data byte has been tramsmitted and ACK received
|
19 | #define TWI_MTX_DATA_NACK 0x30 // Data byte has been tramsmitted and NACK received
|
20 |
|
21 | // TWI Master Receiver staus codes
|
22 | #define TWI_MRX_ADR_ACK 0x40 // SLA+R has been tramsmitted and ACK received
|
23 | #define TWI_MRX_ADR_NACK 0x48 // SLA+R has been tramsmitted and NACK received
|
24 | #define TWI_MRX_DATA_ACK 0x50 // Data byte has been received and ACK tramsmitted
|
25 | #define TWI_MRX_DATA_NACK 0x58 // Data byte has been received and NACK tramsmitted
|
26 |
|
27 | // TWI Slave Transmitter staus codes
|
28 | #define TWI_STX_ADR_ACK 0xA8 // Own SLA+R has been received; ACK has been returned
|
29 | #define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0 // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
|
30 | #define TWI_STX_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted; ACK has been received
|
31 | #define TWI_STX_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted; NOT ACK has been received
|
32 | #define TWI_STX_DATA_ACK_LAST_BYTE 0xC8 // Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
|
33 |
|
34 | // TWI Slave Receiver staus codes
|
35 | #define TWI_SRX_ADR_ACK 0x60 // Own SLA+W has been received ACK has been returned
|
36 | #define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68 // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
|
37 | #define TWI_SRX_GEN_ACK 0x70 // General call address has been received; ACK has been returned
|
38 | #define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78 // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
|
39 | #define TWI_SRX_ADR_DATA_ACK 0x80 // Previously addressed with own SLA+W; data has been received; ACK has been returned
|
40 | #define TWI_SRX_ADR_DATA_NACK 0x88 // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
|
41 | #define TWI_SRX_GEN_DATA_ACK 0x90 // Previously addressed with general call; data has been received; ACK has been returned
|
42 | #define TWI_SRX_GEN_DATA_NACK 0x98 // Previously addressed with general call; data has been received; NOT ACK has been returned
|
43 | #define TWI_SRX_STOP_RESTART 0xA0 // A STOP condition or repeated START condition has been received while still addressed as Slave
|
44 |
|
45 | // TWI Miscellaneous status codes
|
46 | #define TWI_NO_STATE 0xF8 // No relevant state information available; TWINT = “0”
|
47 | #define TWI_BUS_ERROR 0x00 // Bus error due to an illegal START or STOP condition
|
48 |
|
49 | /*******************************************************
|
50 | Public Function: TWIM_Init
|
51 |
|
52 | Purpose: Initialise the TWI Master Interface
|
53 |
|
54 | Input Parameter:
|
55 | - uint16_t TWI_Bitrate (Hz)
|
56 |
|
57 | Return Value: uint8_t
|
58 | - FALSE: Bitrate too high
|
59 | - TRUE: Bitrate OK
|
60 |
|
61 | *******************************************************/
|
62 | uint8_t TWIM_Init (uint32_t TWI_Bitrate)
|
63 | {
|
64 | /*
|
65 | ** Set TWI bitrate
|
66 | ** If bitrate is too high, then error return
|
67 | */
|
68 | TWBR = ((F_CPU/TWI_Bitrate)-16)/2;
|
69 | if (TWBR < 11) return FALSE;
|
70 |
|
71 | return TRUE;
|
72 | }
|
73 | /*******************************************************
|
74 | Public Function: TWIM_Start
|
75 |
|
76 | Purpose: Start the TWI Master Interface
|
77 |
|
78 | Input Parameter:
|
79 | - uint8_t Device address
|
80 | - uint8_t Type of required Operation:
|
81 | TWIM_READ: Read data from the slave
|
82 | TWIM_WRITE: Write data to the slave
|
83 |
|
84 | Return Value: uint8_t
|
85 | - TRUE: OK, TWI Master accessible
|
86 | - FALSE: Error in starting TWI Master
|
87 |
|
88 | *******************************************************/
|
89 | uint8_t TWIM_Start (uint8_t Address, uint8_t TWIM_Type)
|
90 | {
|
91 | uint8_t twst;
|
92 | /*
|
93 | ** Send START condition
|
94 | */
|
95 | TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
|
96 | /*
|
97 | ** Wait until transmission completed
|
98 | */
|
99 | while (!(TWCR & (1<<TWINT)));
|
100 | /*
|
101 | ** Check value of TWI Status Register. Mask prescaler bits.
|
102 | */
|
103 | twst = TWSR & 0xF8;
|
104 | printf("0x%02x\n",twst);
|
105 | if ((twst != TWI_START) && (twst != TWI_REP_START)) return FALSE;
|
106 | /*
|
107 | ** Send device address
|
108 | */
|
109 | TWDR = (Address<<1) + TWIM_Type;
|
110 | TWCR = (1<<TWINT)|(1<<TWEN);
|
111 | /*
|
112 | ** Wait until transmission completed and ACK/NACK has been received
|
113 | */
|
114 | while (!(TWCR & (1<<TWINT)));
|
115 | /*
|
116 | ** Check value of TWI Status Register. Mask prescaler bits.
|
117 | */
|
118 | twst = TWSR & 0xF8;
|
119 | printf("0x%02x\n",twst);
|
120 | if ((twst != TWI_MTX_ADR_ACK) && (twst != TWI_MRX_ADR_ACK)) return FALSE;
|
121 |
|
122 | return TRUE;
|
123 | }
|
124 | /*******************************************************
|
125 | Public Function: TWIM_Stop
|
126 |
|
127 | Purpose: Stop the TWI Master
|
128 |
|
129 | Input Parameter: None
|
130 |
|
131 | Return Value: None
|
132 |
|
133 | *******************************************************/
|
134 | void TWIM_Stop (void)
|
135 | {
|
136 | /*
|
137 | ** Send stop condition
|
138 | */
|
139 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
140 | /*
|
141 | ** Wait until stop condition is executed and bus released
|
142 | */
|
143 | while (TWCR & (1<<TWINT));
|
144 | }
|
145 | /*******************************************************
|
146 | Public Function: TWIM_Write
|
147 |
|
148 | Purpose: Write a byte to the slave
|
149 |
|
150 | Input Parameter:
|
151 | - uint8_t Byte to be sent
|
152 |
|
153 | Return Value: uint8_t
|
154 | - TRUE: OK, Byte sent
|
155 | - FALSE: Error in byte transmission
|
156 |
|
157 | *******************************************************/
|
158 | uint8_t TWIM_Write (uint8_t byte)
|
159 | {
|
160 | uint8_t twst;
|
161 | /*
|
162 | ** Send data to the previously addressed device
|
163 | */
|
164 | TWDR = byte;
|
165 | TWCR = (1<<TWINT)|(1<<TWEN);
|
166 | /*
|
167 | ** Wait until transmission completed
|
168 | */
|
169 | while (!(TWCR & (1<<TWINT)));
|
170 | /*
|
171 | ** Check value of TWI Status Register. Mask prescaler bits
|
172 | */
|
173 | twst = TWSR & 0xF8;
|
174 | printf("0x%02x\n",twst);
|
175 | if (twst != TWI_MTX_DATA_ACK) return 1;
|
176 |
|
177 | return 0;
|
178 | }
|
179 | /*******************************************************
|
180 | Public Function: TWIM_ReadAck
|
181 |
|
182 | Purpose: Read a byte from the slave and request next byte
|
183 |
|
184 | Input Parameter: None
|
185 |
|
186 | Return Value: uint8_t
|
187 | - uint8_t Read byte
|
188 |
|
189 | *******************************************************/
|
190 | uint8_t TWIM_ReadAck (void)
|
191 | {
|
192 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
193 | while (!(TWCR & (1<<TWINT)));
|
194 |
|
195 | return TWDR;
|
196 | }
|
197 | /*******************************************************
|
198 | Public Function: TWIM_ReadAck
|
199 |
|
200 | Purpose: Read the last byte from the slave
|
201 |
|
202 | Input Parameter: None
|
203 |
|
204 | Return Value: uint8_t
|
205 | - uint8_t Read byte
|
206 |
|
207 | *******************************************************/
|
208 | uint8_t TWIM_ReadNack (void)
|
209 | {
|
210 | TWCR = (1<<TWINT)|(1<<TWEN);
|
211 | while(!(TWCR & (1<<TWINT)));
|
212 |
|
213 | return TWDR;
|
214 | }
|