📄 rp6i2cmastertwi.c
字号:
if (TWI_statusReg.lastTransOK)
I2CTWI_getReceivedData(&messageBuffer[0], numberOfBytes+1);
}
/**
* Same as readRegisters, but you need to make sure which register to read yourself - if there
* are any registers at all in your slave device.
*
*/
void I2CTWI_readBytes(uint8_t targetAdr, uint8_t * messageBuffer, uint8_t numberOfBytes)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_operation = I2CTWI_REQUEST_BYTES;
I2CTWI_request_adr = targetAdr;
I2CTWI_requestID = -1;
I2CTWI_request_size = numberOfBytes;
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
if (TWI_statusReg.lastTransOK)
I2CTWI_getReceivedData(&messageBuffer[0], numberOfBytes+1);
}
/**
* Reads a single byte from the slave device.
*/
uint8_t I2CTWI_readByte(uint8_t targetAdr)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_operation = I2CTWI_REQUEST_BYTES;
I2CTWI_request_adr = targetAdr;
I2CTWI_requestID = -1;
I2CTWI_request_size = 1;
while(TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
if (TWI_statusReg.lastTransOK)
return I2CTWI_recbuf[1];
else
return 0;
}
/*****************************************************************************/
// Transmission functions
/**
* Transmits a single byte to a slave device. It waits until the last
* TWI operation is finished (it blocks the normal program flow!) but
* it does NOT wait until this transmission is finished!
* This allows you to perform other things while the transmission is
* in progress!
*/
void I2CTWI_transmitByte(uint8_t targetAdr, uint8_t data)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 2;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
/**
* This is just the same as transmitByte, but you can pass 2 Bytes to
* this function which are then transferred.
*/
void I2CTWI_transmit2Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 3;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data1;
I2CTWI_buf[2] = data2;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
/**
* Transmits 3 Bytes to the slave.
*/
void I2CTWI_transmit3Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 4;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data1;
I2CTWI_buf[2] = data2;
I2CTWI_buf[3] = data3;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
/**
* Transmits 4 Bytes to the slave.
*/
void I2CTWI_transmit4Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 5;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data1;
I2CTWI_buf[2] = data2;
I2CTWI_buf[3] = data3;
I2CTWI_buf[4] = data4;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
/**
* Transmits "numberOfBytes" Bytes to the Slave device. The Bytes need to be
* in the Buffer "msg". Otherwise it is just the same as the other transmit functions.
*/
void I2CTWI_transmitBytes(uint8_t targetAdr, uint8_t *msg, uint8_t numberOfBytes)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
numberOfBytes++;
TWI_msgSize = numberOfBytes;
I2CTWI_buf[0] = targetAdr;
uint8_t i = 0;
for(; i < numberOfBytes; i++)
I2CTWI_buf[i+1] = msg[i];
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
/*****************************************************************************/
// ISR:
/*
* TWI ISR
*/
ISR (TWI_vect)
{
static uint8_t TWI_bufPos = 0;
switch (TWSR)
{
case TWI_START: // START has been transmitted
case TWI_REP_START: // Repeated START has been transmitted
TWI_bufPos = 0; // Set buffer pointer to the TWI Address location
case TWI_MTX_ADR_ACK: // SLA+W has been transmitted and ACK received
case TWI_MTX_DATA_ACK: // Data byte has been transmitted and ACK received
if (TWI_bufPos < TWI_msgSize) {
TWDR = I2CTWI_buf[TWI_bufPos++];
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //
(0<<TWWC); //
} else { // Send STOP after last byte
TWI_statusReg.lastTransOK = 1; // Set status bits to completed successfully.
TWCR = (1<<TWEN)| // TWI Interface enabled
(0<<TWIE)|(1<<TWINT)| // Disable TWI Interrupt and clear the flag
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Initiate a STOP condition.
(0<<TWWC); //
}
break;
case TWI_MRX_DATA_ACK: // Data byte has been received and ACK transmitted
I2CTWI_recbuf[TWI_bufPos++] = TWDR;
case TWI_MRX_ADR_ACK: // SLA+R has been transmitted and ACK received
if (TWI_bufPos < (TWI_msgSize-1) ) { // Detect the last byte to NACK it.
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to read next byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after reception
(0<<TWWC); //
} else { // Send NACK after next reception
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to read next byte
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send NACK after reception
(0<<TWWC); //
}
break;
case TWI_MRX_DATA_NACK: // Data byte has been received and NACK transmitted
I2CTWI_recbuf[TWI_bufPos] = TWDR;
TWI_statusReg.lastTransOK = 1; // Set status bits to completed successfully.
TWCR = (1<<TWEN)| // TWI Interface enabled
(0<<TWIE)|(1<<TWINT)| // Disable TWI Interrupt and clear the flag
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Initiate a STOP condition.
(0<<TWWC); //
break;
case TWI_ARB_LOST: // Arbitration lost
TWI_TWSR_state = TWSR; // Store TWSR
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag
(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a (RE)START condition.
(0<<TWWC); //
break;
default:
TWI_TWSR_state = TWSR; // Store TWSR
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
(0<<TWIE)|(1<<TWINT)| // Disable Interupt
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // No Signal requests
(0<<TWWC);
break;
}
}
/******************************************************************************
* Additional info
* ****************************************************************************
* Changelog:
* - v. 1.0 (initial release) 16.05.2007 by Dominik S. Herwald
*
* ****************************************************************************
* Bugs, feedback, questions and modifications can be posted on the AREXX Forum
* on http://www.arexx.com/forum/ !
* Of course you can also write us an e-mail to: info@arexx.nl
* AREXX Engineering may publish updates from time to time on AREXX.com!
* ****************************************************************************
* - LICENSE -
* GNU GPL v2 (http://www.gnu.org/licenses/gpl.txt, a local copy can be found
* on the RP6 CD in the RP6 sorce code folders!)
* This program is free software. You can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
* ****************************************************************************
*/
/*****************************************************************************/
// EOF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -