add Wire::end()
This commit is contained in:
parent
726a943393
commit
7157b88f4a
4 changed files with 75 additions and 29 deletions
|
|
@ -77,9 +77,14 @@ void TwoWire::begin(int address)
|
|||
begin((uint8_t)address);
|
||||
}
|
||||
|
||||
void TwoWire::setClock(uint32_t frequency)
|
||||
void TwoWire::end(void)
|
||||
{
|
||||
TWBR = ((F_CPU / frequency) - 16) / 2;
|
||||
twi_disable();
|
||||
}
|
||||
|
||||
void TwoWire::setClock(uint32_t clock)
|
||||
{
|
||||
twi_setFrequency(clock);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
|
||||
#define BUFFER_LENGTH 32
|
||||
|
||||
// WIRE_HAS_END means Wire has end()
|
||||
#define WIRE_HAS_END 1
|
||||
|
||||
class TwoWire : public Stream
|
||||
{
|
||||
private:
|
||||
|
|
@ -55,6 +58,7 @@ class TwoWire : public Stream
|
|||
void begin();
|
||||
void begin(uint8_t);
|
||||
void begin(int);
|
||||
void end();
|
||||
void setClock(uint32_t);
|
||||
void beginTransmission(uint8_t);
|
||||
void beginTransmission(int);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,22 @@ void twi_init(void)
|
|||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function twi_disable
|
||||
* Desc disables twi pins
|
||||
* Input none
|
||||
* Output none
|
||||
*/
|
||||
void twi_disable(void)
|
||||
{
|
||||
// disable twi module, acks, and twi interrupt
|
||||
TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));
|
||||
|
||||
// deactivate internal pullups for twi.
|
||||
digitalWrite(SDA, 0);
|
||||
digitalWrite(SCL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function twi_slaveInit
|
||||
* Desc sets slave address and enables interrupt
|
||||
|
|
@ -104,6 +120,22 @@ void twi_setAddress(uint8_t address)
|
|||
TWAR = address << 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function twi_setClock
|
||||
* Desc sets twi bit rate
|
||||
* Input Clock Frequency
|
||||
* Output none
|
||||
*/
|
||||
void twi_setFrequency(uint32_t frequency)
|
||||
{
|
||||
TWBR = ((F_CPU / frequency) - 16) / 2;
|
||||
|
||||
/* twi bit rate formula from atmega128 manual pg 204
|
||||
SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
|
||||
note: TWBR should be 10 or higher for master mode
|
||||
It is 72 for a 16mhz Wiring board with 100kHz TWI */
|
||||
}
|
||||
|
||||
/*
|
||||
* Function twi_readFrom
|
||||
* Desc attempts to become twi bus master and read a
|
||||
|
|
@ -155,18 +187,19 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
|
|||
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
|
||||
TWDR = twi_slarw;
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
|
||||
}
|
||||
else
|
||||
} else {
|
||||
// send start condition
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
|
||||
}
|
||||
|
||||
// wait for read operation to complete
|
||||
while(TWI_MRX == twi_state){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (twi_masterBufferIndex < length)
|
||||
if (twi_masterBufferIndex < length) {
|
||||
length = twi_masterBufferIndex;
|
||||
}
|
||||
|
||||
// copy twi buffer to data
|
||||
for(i = 0; i < length; ++i){
|
||||
|
|
@ -235,10 +268,10 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
|
|||
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
|
||||
TWDR = twi_slarw;
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
|
||||
}
|
||||
else
|
||||
} else {
|
||||
// send start condition
|
||||
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
|
||||
}
|
||||
|
||||
// wait for write operation to complete
|
||||
while(wait && (TWI_MTX == twi_state)){
|
||||
|
|
@ -322,7 +355,7 @@ void twi_reply(uint8_t ack)
|
|||
if(ack){
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
|
||||
}else{
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
|
||||
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,16 +415,16 @@ ISR(TWI_vect)
|
|||
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
|
||||
twi_reply(1);
|
||||
}else{
|
||||
if (twi_sendStop)
|
||||
if (twi_sendStop){
|
||||
twi_stop();
|
||||
else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
} else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TW_MT_SLA_NACK: // address sent, nack received
|
||||
|
|
@ -411,6 +444,7 @@ ISR(TWI_vect)
|
|||
case TW_MR_DATA_ACK: // data received, ack sent
|
||||
// put byte into buffer
|
||||
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
|
||||
__attribute__ ((fallthrough));
|
||||
case TW_MR_SLA_ACK: // address sent, ack received
|
||||
// ack if more bytes are expected, otherwise nack
|
||||
if(twi_masterBufferIndex < twi_masterBufferLength){
|
||||
|
|
@ -422,17 +456,17 @@ ISR(TWI_vect)
|
|||
case TW_MR_DATA_NACK: // data received, nack sent
|
||||
// put final byte into buffer
|
||||
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
|
||||
if (twi_sendStop)
|
||||
twi_stop();
|
||||
else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
break;
|
||||
if (twi_sendStop){
|
||||
twi_stop();
|
||||
} else {
|
||||
twi_inRepStart = true; // we're gonna send the START
|
||||
// don't enable the interrupt. We'll generate the start, but we
|
||||
// avoid handling the interrupt until we're in the next transaction,
|
||||
// at the point where we would normally issue the start.
|
||||
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
|
||||
twi_state = TWI_READY;
|
||||
}
|
||||
break;
|
||||
case TW_MR_SLA_NACK: // address sent, nack received
|
||||
twi_stop();
|
||||
break;
|
||||
|
|
@ -498,6 +532,7 @@ ISR(TWI_vect)
|
|||
twi_txBufferLength = 1;
|
||||
twi_txBuffer[0] = 0x00;
|
||||
}
|
||||
__attribute__ ((fallthrough));
|
||||
// transmit first byte from buffer, fall
|
||||
case TW_ST_DATA_ACK: // byte sent, ack returned
|
||||
// copy data to output register
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
#define TWI_STX 4
|
||||
|
||||
void twi_init(void);
|
||||
void twi_disable(void);
|
||||
void twi_setAddress(uint8_t);
|
||||
void twi_setFrequency(uint32_t);
|
||||
uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
|
||||
uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
|
||||
uint8_t twi_transmit(const uint8_t*, uint8_t);
|
||||
|
|
|
|||
Loading…
Reference in a new issue