4 #include "interrupts.h"
15 extern void twi_isr_entry(void);
19 TWI_UNINITIALISED = 0,
28 static U32 twi_pending;
47 return (twi_state == TWI_TX_BUSY || twi_state == TWI_RX_BUSY);
53 return (twi_state >= TWI_IDLE && twi_state <= TWI_RX_DONE);
59 U32 status = *AT91C_TWI_SR;
61 if ((status & AT91C_TWI_RXRDY) && twi_state == TWI_RX_BUSY) {
66 *twi_ptr = *AT91C_TWI_RHR;
69 if (twi_pending == 1) {
70 /* second last byte -- issue a stop on the next byte */
71 *AT91C_TWI_CR = AT91C_TWI_STOP;
75 twi_state = TWI_RX_DONE;
81 if ((status & AT91C_TWI_TXRDY) && twi_state == TWI_TX_BUSY) {
83 /* Still Stuff to send */
84 *AT91C_TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_START;
85 if (twi_pending == 1) {
86 *AT91C_TWI_CR = AT91C_TWI_STOP;
88 *AT91C_TWI_THR = *twi_ptr;
95 /* everything has been sent */
96 twi_state = TWI_TX_DONE;
102 if (status & AT91C_TWI_OVRE) {
105 *AT91C_TWI_CR = AT91C_TWI_STOP;
107 twi_state = TWI_FAILED;
111 if (status & AT91C_TWI_UNRE) {
115 twi_state = TWI_FAILED;
118 if (status & AT91C_TWI_NACK) {
122 twi_state = TWI_UNINITIALISED;
135 *AT91C_PMC_PCER = (1 << AT91C_PERIPHERAL_ID_PIOA) | /* Need PIO too */
136 (1 << AT91C_PERIPHERAL_ID_TWI); /* TWI clock domain */
138 /* Set up pin as an IO pin for clocking till clean */
139 *AT91C_PIOA_MDER = (1 << 3) | (1 << 4);
140 *AT91C_PIOA_PER = (1 << 3) | (1 << 4);
141 *AT91C_PIOA_ODR = (1 << 3);
142 *AT91C_PIOA_OER = (1 << 4);
144 while (clocks > 0 && !(*AT91C_PIOA_PDSR & (1 << 3))) {
146 *AT91C_PIOA_CODR = (1 << 4);
147 systick_wait_ns(1500);
148 *AT91C_PIOA_SODR = (1 << 4);
149 systick_wait_ns(1500);
153 *AT91C_PIOA_PDR = (1 << 3) | (1 << 4);
154 *AT91C_PIOA_ASR = (1 << 3) | (1 << 4);
156 *AT91C_TWI_CR = 0x88; /* Disable & reset */
158 *AT91C_TWI_CWGR = 0x020f0f; /* Set for 380kHz */
159 *AT91C_TWI_CR = 0x04; /* Enable as master */
167 i_state = interrupts_get_and_disable();
169 /* Todo: set up interrupt */
170 *AT91C_TWI_IDR = ~0; /* Disable all interrupt sources */
171 aic_mask_off(AT91C_PERIPHERAL_ID_TWI);
172 aic_set_vector(AT91C_PERIPHERAL_ID_TWI, AIC_INT_LEVEL_ABOVE_NORMAL,
174 aic_mask_on(AT91C_PERIPHERAL_ID_TWI);
179 /* Init peripheral */
181 twi_state = TWI_IDLE;
192 twi_start_read(U32 dev_addr, U32 int_addr_bytes, U32 int_addr, U8 *data,
196 ((dev_addr & 0x7f) << 16) | ((int_addr_bytes & 3) << 8) | (1 << 12);
201 twi_state = TWI_RX_BUSY;
202 *AT91C_TWI_IDR = ~0; /* Disable all interrupts */
204 twi_pending = nBytes;
205 dummy = *AT91C_TWI_SR;
206 dummy = *AT91C_TWI_RHR;
207 // *AT91C_AIC_ICCR = ( 1<< AT91C_PERIPHERAL_ID_TWI);
208 *AT91C_TWI_MMR = mode;
209 *AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
210 // dummy = *AT91C_TWI_SR;
211 *AT91C_TWI_IER = 0x01C2;
217 twi_start_write(U32 dev_addr, U32 int_addr_bytes, U32 int_addr,
218 const U8 *data, U32 nBytes)
220 U32 mode = ((dev_addr & 0x7f) << 16) | ((int_addr_bytes & 3) << 8);
223 twi_state = TWI_TX_BUSY;
224 *AT91C_TWI_IDR = ~0; /* Disable all interrupts */
226 twi_pending = nBytes;
228 *AT91C_TWI_MMR = mode;
229 *AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
230 *AT91C_TWI_IER = 0x1C4;