Skip to content

Commit 6d89e50

Browse files
authored
Merge pull request #19 from adafruit/add-wire-end
add Wire::end() for busio
2 parents 726a943 + 7157b88 commit 6d89e50

File tree

4 files changed

+75
-29
lines changed

4 files changed

+75
-29
lines changed

libraries/Wire/Wire.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,14 @@ void TwoWire::begin(int address)
7777
begin((uint8_t)address);
7878
}
7979

80-
void TwoWire::setClock(uint32_t frequency)
80+
void TwoWire::end(void)
8181
{
82-
TWBR = ((F_CPU / frequency) - 16) / 2;
82+
twi_disable();
83+
}
84+
85+
void TwoWire::setClock(uint32_t clock)
86+
{
87+
twi_setFrequency(clock);
8388
}
8489

8590
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)

libraries/Wire/Wire.h

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333

3434
#define BUFFER_LENGTH 32
3535

36+
// WIRE_HAS_END means Wire has end()
37+
#define WIRE_HAS_END 1
38+
3639
class TwoWire : public Stream
3740
{
3841
private:
@@ -55,6 +58,7 @@ class TwoWire : public Stream
5558
void begin();
5659
void begin(uint8_t);
5760
void begin(int);
61+
void end();
5862
void setClock(uint32_t);
5963
void beginTransmission(uint8_t);
6064
void beginTransmission(int);

libraries/Wire/utility/twi.c

+62-27
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ void twi_init(void)
9292
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
9393
}
9494

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+
95111
/*
96112
* Function twi_slaveInit
97113
* Desc sets slave address and enables interrupt
@@ -104,6 +120,22 @@ void twi_setAddress(uint8_t address)
104120
TWAR = address << 1;
105121
}
106122

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+
107139
/*
108140
* Function twi_readFrom
109141
* 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
155187
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
156188
TWDR = twi_slarw;
157189
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
158-
}
159-
else
190+
} else {
160191
// send start condition
161192
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
193+
}
162194

163195
// wait for read operation to complete
164196
while(TWI_MRX == twi_state){
165197
continue;
166198
}
167199

168-
if (twi_masterBufferIndex < length)
200+
if (twi_masterBufferIndex < length) {
169201
length = twi_masterBufferIndex;
202+
}
170203

171204
// copy twi buffer to data
172205
for(i = 0; i < length; ++i){
173206
data[i] = twi_masterBuffer[i];
174207
}
175-
208+
176209
return length;
177210
}
178211

@@ -235,10 +268,10 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
235268
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
236269
TWDR = twi_slarw;
237270
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
238-
}
239-
else
271+
} else {
240272
// send start condition
241273
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
274+
}
242275

243276
// wait for write operation to complete
244277
while(wait && (TWI_MTX == twi_state)){
@@ -322,7 +355,7 @@ void twi_reply(uint8_t ack)
322355
if(ack){
323356
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
324357
}else{
325-
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
358+
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
326359
}
327360
}
328361

@@ -382,16 +415,16 @@ ISR(TWI_vect)
382415
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
383416
twi_reply(1);
384417
}else{
385-
if (twi_sendStop)
418+
if (twi_sendStop){
386419
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+
}
395428
}
396429
break;
397430
case TW_MT_SLA_NACK: // address sent, nack received
@@ -411,6 +444,7 @@ ISR(TWI_vect)
411444
case TW_MR_DATA_ACK: // data received, ack sent
412445
// put byte into buffer
413446
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
447+
__attribute__ ((fallthrough));
414448
case TW_MR_SLA_ACK: // address sent, ack received
415449
// ack if more bytes are expected, otherwise nack
416450
if(twi_masterBufferIndex < twi_masterBufferLength){
@@ -422,17 +456,17 @@ ISR(TWI_vect)
422456
case TW_MR_DATA_NACK: // data received, nack sent
423457
// put final byte into buffer
424458
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;
436470
case TW_MR_SLA_NACK: // address sent, nack received
437471
twi_stop();
438472
break;
@@ -498,6 +532,7 @@ ISR(TWI_vect)
498532
twi_txBufferLength = 1;
499533
twi_txBuffer[0] = 0x00;
500534
}
535+
__attribute__ ((fallthrough));
501536
// transmit first byte from buffer, fall
502537
case TW_ST_DATA_ACK: // byte sent, ack returned
503538
// copy data to output register

libraries/Wire/utility/twi.h

+2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
#define TWI_STX 4
4040

4141
void twi_init(void);
42+
void twi_disable(void);
4243
void twi_setAddress(uint8_t);
44+
void twi_setFrequency(uint32_t);
4345
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
4446
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
4547
uint8_t twi_transmit(const uint8_t*, uint8_t);

0 commit comments

Comments
 (0)