@@ -92,6 +92,22 @@ void twi_init(void)
92
92
TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWEA );
93
93
}
94
94
95
+ /*
96
+ * Function twi_disable
97
+ * Desc disables twi pins
98
+ * Input none
99
+ * Output none
100
+ */
101
+ void twi_disable (void )
102
+ {
103
+ // disable twi module, acks, and twi interrupt
104
+ TWCR &= ~(_BV (TWEN ) | _BV (TWIE ) | _BV (TWEA ));
105
+
106
+ // deactivate internal pullups for twi.
107
+ digitalWrite (SDA , 0 );
108
+ digitalWrite (SCL , 0 );
109
+ }
110
+
95
111
/*
96
112
* Function twi_slaveInit
97
113
* Desc sets slave address and enables interrupt
@@ -104,6 +120,22 @@ void twi_setAddress(uint8_t address)
104
120
TWAR = address << 1 ;
105
121
}
106
122
123
+ /*
124
+ * Function twi_setClock
125
+ * Desc sets twi bit rate
126
+ * Input Clock Frequency
127
+ * Output none
128
+ */
129
+ void twi_setFrequency (uint32_t frequency )
130
+ {
131
+ TWBR = ((F_CPU / frequency ) - 16 ) / 2 ;
132
+
133
+ /* twi bit rate formula from atmega128 manual pg 204
134
+ SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
135
+ note: TWBR should be 10 or higher for master mode
136
+ It is 72 for a 16mhz Wiring board with 100kHz TWI */
137
+ }
138
+
107
139
/*
108
140
* Function twi_readFrom
109
141
* Desc attempts to become twi bus master and read a
@@ -155,24 +187,25 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
155
187
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
156
188
TWDR = twi_slarw ;
157
189
TWCR = _BV (TWINT ) | _BV (TWEA ) | _BV (TWEN ) | _BV (TWIE ); // enable INTs, but not START
158
- }
159
- else
190
+ } else {
160
191
// send start condition
161
192
TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWEA ) | _BV (TWINT ) | _BV (TWSTA );
193
+ }
162
194
163
195
// wait for read operation to complete
164
196
while (TWI_MRX == twi_state ){
165
197
continue ;
166
198
}
167
199
168
- if (twi_masterBufferIndex < length )
200
+ if (twi_masterBufferIndex < length ) {
169
201
length = twi_masterBufferIndex ;
202
+ }
170
203
171
204
// copy twi buffer to data
172
205
for (i = 0 ; i < length ; ++ i ){
173
206
data [i ] = twi_masterBuffer [i ];
174
207
}
175
-
208
+
176
209
return length ;
177
210
}
178
211
@@ -235,10 +268,10 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
235
268
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
236
269
TWDR = twi_slarw ;
237
270
TWCR = _BV (TWINT ) | _BV (TWEA ) | _BV (TWEN ) | _BV (TWIE ); // enable INTs, but not START
238
- }
239
- else
271
+ } else {
240
272
// send start condition
241
273
TWCR = _BV (TWINT ) | _BV (TWEA ) | _BV (TWEN ) | _BV (TWIE ) | _BV (TWSTA ); // enable INTs
274
+ }
242
275
243
276
// wait for write operation to complete
244
277
while (wait && (TWI_MTX == twi_state )){
@@ -322,7 +355,7 @@ void twi_reply(uint8_t ack)
322
355
if (ack ){
323
356
TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWINT ) | _BV (TWEA );
324
357
}else {
325
- TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWINT );
358
+ TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWINT );
326
359
}
327
360
}
328
361
@@ -382,16 +415,16 @@ ISR(TWI_vect)
382
415
TWDR = twi_masterBuffer [twi_masterBufferIndex ++ ];
383
416
twi_reply (1 );
384
417
}else {
385
- if (twi_sendStop )
418
+ if (twi_sendStop ){
386
419
twi_stop ();
387
- else {
388
- twi_inRepStart = true; // we're gonna send the START
389
- // don't enable the interrupt. We'll generate the start, but we
390
- // avoid handling the interrupt until we're in the next transaction,
391
- // at the point where we would normally issue the start.
392
- TWCR = _BV (TWINT ) | _BV (TWSTA )| _BV (TWEN ) ;
393
- twi_state = TWI_READY ;
394
- }
420
+ } else {
421
+ twi_inRepStart = true; // we're gonna send the START
422
+ // don't enable the interrupt. We'll generate the start, but we
423
+ // avoid handling the interrupt until we're in the next transaction,
424
+ // at the point where we would normally issue the start.
425
+ TWCR = _BV (TWINT ) | _BV (TWSTA )| _BV (TWEN ) ;
426
+ twi_state = TWI_READY ;
427
+ }
395
428
}
396
429
break ;
397
430
case TW_MT_SLA_NACK : // address sent, nack received
@@ -411,6 +444,7 @@ ISR(TWI_vect)
411
444
case TW_MR_DATA_ACK : // data received, ack sent
412
445
// put byte into buffer
413
446
twi_masterBuffer [twi_masterBufferIndex ++ ] = TWDR ;
447
+ __attribute__ ((fallthrough ));
414
448
case TW_MR_SLA_ACK : // address sent, ack received
415
449
// ack if more bytes are expected, otherwise nack
416
450
if (twi_masterBufferIndex < twi_masterBufferLength ){
@@ -422,17 +456,17 @@ ISR(TWI_vect)
422
456
case TW_MR_DATA_NACK : // data received, nack sent
423
457
// put final byte into buffer
424
458
twi_masterBuffer [twi_masterBufferIndex ++ ] = TWDR ;
425
- if (twi_sendStop )
426
- twi_stop ();
427
- else {
428
- twi_inRepStart = true; // we're gonna send the START
429
- // don't enable the interrupt. We'll generate the start, but we
430
- // avoid handling the interrupt until we're in the next transaction,
431
- // at the point where we would normally issue the start.
432
- TWCR = _BV (TWINT ) | _BV (TWSTA )| _BV (TWEN ) ;
433
- twi_state = TWI_READY ;
434
- }
435
- break ;
459
+ if (twi_sendStop ){
460
+ twi_stop ();
461
+ } else {
462
+ twi_inRepStart = true; // we're gonna send the START
463
+ // don't enable the interrupt. We'll generate the start, but we
464
+ // avoid handling the interrupt until we're in the next transaction,
465
+ // at the point where we would normally issue the start.
466
+ TWCR = _BV (TWINT ) | _BV (TWSTA )| _BV (TWEN ) ;
467
+ twi_state = TWI_READY ;
468
+ }
469
+ break ;
436
470
case TW_MR_SLA_NACK : // address sent, nack received
437
471
twi_stop ();
438
472
break ;
@@ -498,6 +532,7 @@ ISR(TWI_vect)
498
532
twi_txBufferLength = 1 ;
499
533
twi_txBuffer [0 ] = 0x00 ;
500
534
}
535
+ __attribute__ ((fallthrough ));
501
536
// transmit first byte from buffer, fall
502
537
case TW_ST_DATA_ACK : // byte sent, ack returned
503
538
// copy data to output register
0 commit comments