00001
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include "twi.h"
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 int twi_set_speed(unsigned int speed, unsigned long cpu_hz)
00069 {
00070 volatile avr32_twi_t *twi = &AVR32_TWI;
00071 unsigned int cldiv;
00072 unsigned int ckdiv = 0;
00073
00074 cldiv = cpu_hz / (speed * 2) - 4;
00075
00076 while (cldiv > 255)
00077 {
00078 ckdiv++;
00079 cldiv /= 2;
00080 }
00081
00082 twi->cwgr = ( cldiv | (cldiv << 8) | (ckdiv << 16) );
00083
00084 return TWI_SUCCESS;
00085
00086 }
00087
00088 int twi_init(struct twi_options_t * opt)
00089 {
00090
00091 volatile avr32_twi_t *twi = &AVR32_TWI;
00092
00093
00094 twi->cr =
00095 (1<<AVR32_TWI_CR_MSEN_OFFSET);
00096 twi->iadr = opt->twi_addr;
00097
00098 return twi_set_speed(opt->speed, opt->cpu_hz);
00099
00100 }
00101
00102 int twi_probe(char chip_addr)
00103 {
00104 volatile avr32_twi_t *twi = &AVR32_TWI;
00105 int timeout = TWI_TIMEOUT;
00106
00107 twi->mmr = (chip_addr << 16) | (1<<AVR32_TWI_MMR_MREAD_OFFSET);
00108 twi->iadr = 0;
00109 twi->cr = (1<<AVR32_TWI_CR_START_OFFSET) | (1<<AVR32_TWI_CR_STOP_OFFSET);
00110
00111 do {
00112 if ((twi->sr) & (1<<AVR32_TWI_SR_RXRDY_OFFSET))
00113 {
00114 return TWI_SUCCESS;
00115 }
00116 } while (!(twi->sr & (1<<AVR32_TWI_SR_TXCOMP_OFFSET)) && --timeout);
00117
00118 return TWI_NO_CHIP_FOUND;
00119 }
00120
00121 int twi_read(struct twi_package_t * package)
00122 {
00123 volatile avr32_twi_t *twi = &AVR32_TWI;
00124 unsigned int i = 0;
00125 unsigned int timeout = TWI_TIMEOUT;
00126
00127 if (package->length == 0)
00128 {
00129 return TWI_INVALID_ARGUMENT;
00130 }
00131
00132
00133 for (i = 0; i< package->length; i++)
00134 package->buffer[i] = '_';
00135 i=0;
00136
00137 twi->mmr = (package->chip << AVR32_TWI_MMR_DADR_OFFSET) |
00138 ((package->addr_length &3) << 8) |
00139 (1<<AVR32_TWI_MMR_MREAD_OFFSET);
00140 twi->iadr = package->addr;
00141
00142
00143 twi->cr = (1<<AVR32_TWI_CR_START_OFFSET);
00144
00145
00146
00147 while (i < package->length){
00148 if (twi->sr & (1<<AVR32_TWI_SR_RXRDY_OFFSET)){
00149 package->buffer[i++] = twi->rhr;
00150
00151 }
00152
00153
00154 while (!(twi->sr & (1<<AVR32_TWI_SR_RXRDY_OFFSET)) && (--timeout));
00155
00156
00157 if(timeout==0){
00158 return TWI_RECEIVE_NACK;
00159 }
00160
00161 timeout=TWI_TIMEOUT;
00162 }
00163
00164
00165 twi->cr |= (1<<AVR32_TWI_CR_STOP_OFFSET);
00166
00167
00168 package->buffer[i++] = '\0';
00169
00170 if (twi->sr & (1<<AVR32_TWI_SR_NACK_OFFSET))
00171 return TWI_RECEIVE_NACK;
00172
00173 if (i < package->length)
00174 return TWI_INVALID_ARGUMENT;
00175 return i;
00176 }
00177
00178
00179 int twi_write(struct twi_package_t * package)
00180 {
00181 volatile avr32_twi_t *twi = &AVR32_TWI;
00182 int i = 0;
00183 int timeout = TWI_TIMEOUT;
00184
00185
00186 if (package->length == 0)
00187 {
00188 return TWI_INVALID_ARGUMENT;
00189 }
00190
00191 twi->cr |= (0<<AVR32_TWI_CR_MSDIS_OFFSET);
00192
00193
00194 twi->mmr = (0<<AVR32_TWI_MMR_MREAD_OFFSET) | \
00195 (package->chip << AVR32_TWI_MMR_DADR_OFFSET) | \
00196 ((package->addr_length & 3) << 8);
00197
00198 twi->iadr = package->addr;
00199
00200
00201 twi->cr |= (1<<AVR32_TWI_CR_START_OFFSET);
00202
00203
00204 while (i < package->length){
00205
00206 if (twi->sr & (1<<AVR32_TWI_SR_TXRDY_OFFSET))
00207 twi->thr = package->buffer[i++];
00208
00209
00210 while (!(twi->sr & (1<<AVR32_TWI_SR_TXCOMP_OFFSET)) && timeout--);
00211
00212 if(timeout==0)
00213 return TWI_RECEIVE_NACK;
00214
00215 timeout=TWI_TIMEOUT;
00216
00217 }
00218
00219
00220
00221 twi->cr |= (1<<AVR32_TWI_CR_STOP_OFFSET);
00222
00223
00224 if (twi->sr & (1<<AVR32_TWI_SR_NACK_OFFSET))
00225 return TWI_SEND_NACK;
00226
00227
00228 if (i < package->length)
00229 {
00230
00231 return TWI_INVALID_ARGUMENT;
00232 }
00233
00234
00235
00236 return i;
00237 }
00238