reading EDID information from display and submission to host works
This commit is contained in:
@@ -68,6 +68,10 @@
|
||||
|
||||
#include "twi_master_driver.h"
|
||||
|
||||
static void TWI_MasterWriteHandler(TWI_Master_t *twi);
|
||||
static void TWI_MasterReadHandler(TWI_Master_t *twi);
|
||||
static void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result);
|
||||
static void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi);
|
||||
|
||||
/*! \brief Initialize the TWI module.
|
||||
*
|
||||
@@ -86,14 +90,28 @@ void TWI_MasterInit(TWI_Master_t *twi,
|
||||
uint8_t baudRateRegisterSetting)
|
||||
{
|
||||
twi->interface = module;
|
||||
twi->interface->CTRL = TWI_SDAHOLD_bm;
|
||||
twi->interface->MASTER.CTRLA = intLevel |
|
||||
TWI_MASTER_RIEN_bm |
|
||||
TWI_MASTER_WIEN_bm |
|
||||
TWI_MASTER_ENABLE_bm;
|
||||
|
||||
#if 1
|
||||
twi->interface->MASTER.CTRLB =
|
||||
TWI_MASTER_TIMEOUT_200US_gc;
|
||||
#endif
|
||||
|
||||
twi->interface->MASTER.BAUD = baudRateRegisterSetting;
|
||||
twi->interface->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
|
||||
|
||||
twi->status = TWIM_STATUS_READY;
|
||||
}
|
||||
|
||||
void TWI_MasterForceIdle(TWI_Master_t *twi)
|
||||
{
|
||||
twi->interface->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
|
||||
twi->status = TWIM_STATUS_READY;
|
||||
}
|
||||
|
||||
/*! \brief Returns the TWI bus state.
|
||||
*
|
||||
@@ -128,7 +146,7 @@ TWI_MASTER_BUSSTATE_t TWI_MasterState(TWI_Master_t *twi)
|
||||
*/
|
||||
bool TWI_MasterReady(TWI_Master_t *twi)
|
||||
{
|
||||
bool twi_status = (twi->status & TWIM_STATUS_READY);
|
||||
bool twi_status = (twi->status == TWIM_STATUS_READY);
|
||||
return twi_status;
|
||||
}
|
||||
|
||||
@@ -147,10 +165,14 @@ bool TWI_MasterReady(TWI_Master_t *twi)
|
||||
*/
|
||||
bool TWI_MasterWrite(TWI_Master_t *twi,
|
||||
uint8_t address,
|
||||
uint8_t *writeData,
|
||||
uint8_t const *writeData,
|
||||
uint8_t bytesToWrite)
|
||||
{
|
||||
bool twi_status = TWI_MasterWriteRead(twi, address, writeData, bytesToWrite, 0);
|
||||
bool twi_status = TWI_MasterWriteRead(twi,
|
||||
address,
|
||||
writeData, bytesToWrite,
|
||||
NULL, 0);
|
||||
|
||||
return twi_status;
|
||||
}
|
||||
|
||||
@@ -168,9 +190,14 @@ bool TWI_MasterWrite(TWI_Master_t *twi,
|
||||
*/
|
||||
bool TWI_MasterRead(TWI_Master_t *twi,
|
||||
uint8_t address,
|
||||
uint8_t *readData,
|
||||
uint8_t bytesToRead)
|
||||
{
|
||||
bool twi_status = TWI_MasterWriteRead(twi, address, 0, 0, bytesToRead);
|
||||
bool twi_status = TWI_MasterWriteRead(twi,
|
||||
address,
|
||||
NULL, 0,
|
||||
readData, bytesToRead);
|
||||
|
||||
return twi_status;
|
||||
}
|
||||
|
||||
@@ -192,55 +219,57 @@ bool TWI_MasterRead(TWI_Master_t *twi,
|
||||
*/
|
||||
bool TWI_MasterWriteRead(TWI_Master_t *twi,
|
||||
uint8_t address,
|
||||
uint8_t *writeData,
|
||||
uint8_t const *writeData,
|
||||
uint8_t bytesToWrite,
|
||||
uint8_t *readData,
|
||||
uint8_t bytesToRead)
|
||||
{
|
||||
/*Parameter sanity check. */
|
||||
if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
|
||||
return false;
|
||||
if( !bytesToWrite || !writeData ) {
|
||||
writeData = NULL;
|
||||
bytesToWrite = 0;
|
||||
}
|
||||
if (bytesToRead > TWIM_READ_BUFFER_SIZE) {
|
||||
return false;
|
||||
if( !bytesToRead || !readData ) {
|
||||
readData = NULL;
|
||||
bytesToRead = 0;
|
||||
}
|
||||
|
||||
/*Initiate transaction if bus is ready. */
|
||||
if (twi->status == TWIM_STATUS_READY) {
|
||||
|
||||
twi->status = TWIM_STATUS_BUSY;
|
||||
twi->result = TWIM_RESULT_UNKNOWN;
|
||||
|
||||
twi->address = address<<1;
|
||||
|
||||
/* Fill write data buffer. */
|
||||
for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) {
|
||||
twi->writeData[bufferIndex] = writeData[bufferIndex];
|
||||
}
|
||||
|
||||
twi->bytesToWrite = bytesToWrite;
|
||||
twi->bytesToRead = bytesToRead;
|
||||
twi->bytesWritten = 0;
|
||||
twi->bytesRead = 0;
|
||||
|
||||
/* If write command, send the START condition + Address +
|
||||
* 'R/_W = 0'
|
||||
*/
|
||||
if (twi->bytesToWrite > 0) {
|
||||
uint8_t writeAddress = twi->address & ~0x01;
|
||||
twi->interface->MASTER.ADDR = writeAddress;
|
||||
}
|
||||
|
||||
/* If read command, send the START condition + Address +
|
||||
* 'R/_W = 1'
|
||||
*/
|
||||
else if (twi->bytesToRead > 0) {
|
||||
uint8_t readAddress = twi->address | 0x01;
|
||||
twi->interface->MASTER.ADDR = readAddress;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if( twi->status != TWIM_STATUS_READY ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
twi->status = TWIM_STATUS_BUSY;
|
||||
twi->result = TWIM_RESULT_UNKNOWN;
|
||||
|
||||
twi->address = (address << 1);
|
||||
|
||||
twi->writeData = writeData;
|
||||
twi->readData = readData;
|
||||
twi->bytesToWrite = bytesToWrite;
|
||||
twi->bytesToRead = bytesToRead;
|
||||
twi->bytesWritten = 0;
|
||||
twi->bytesRead = 0;
|
||||
|
||||
/* If write command, send the START condition + Address +
|
||||
* 'R/_W = 0'
|
||||
*/
|
||||
if( twi->bytesToWrite > 0 ) {
|
||||
uint8_t const writeAddress = twi->address & ~0x01;
|
||||
twi->interface->MASTER.ADDR = writeAddress;
|
||||
|
||||
uint8_t const data = twi->writeData[0];
|
||||
twi->interface->MASTER.DATA = data;
|
||||
twi->bytesWritten++;
|
||||
} else
|
||||
/* If read command, send the START condition + Address +
|
||||
* 'R/_W = 1'
|
||||
*/
|
||||
if( twi->bytesToRead > 0 ) {
|
||||
uint8_t const readAddress = twi->address | 0x01;
|
||||
twi->interface->MASTER.ADDR = readAddress;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -252,28 +281,64 @@ bool TWI_MasterWriteRead(TWI_Master_t *twi,
|
||||
*/
|
||||
void TWI_MasterInterruptHandler(TWI_Master_t *twi)
|
||||
{
|
||||
uint8_t currentStatus = twi->interface->MASTER.STATUS;
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
uint8_t const currentStatus = twi->interface->MASTER.STATUS;
|
||||
|
||||
/* If arbitration lost or bus error. */
|
||||
if ((currentStatus & TWI_MASTER_ARBLOST_bm) ||
|
||||
(currentStatus & TWI_MASTER_BUSERR_bm)) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
|
||||
TWI_MasterArbitrationLostBusErrorHandler(twi);
|
||||
}
|
||||
|
||||
twi->interface->MASTER.STATUS =
|
||||
currentStatus
|
||||
| TWI_MASTER_ARBLOST_bm
|
||||
| TWI_MASTER_BUSERR_bm;
|
||||
} else
|
||||
/* If master write interrupt. */
|
||||
else if (currentStatus & TWI_MASTER_WIF_bm) {
|
||||
if (currentStatus & TWI_MASTER_WIF_bm) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
TWI_MasterWriteHandler(twi);
|
||||
}
|
||||
|
||||
twi->interface->MASTER.STATUS =
|
||||
currentStatus
|
||||
| TWI_MASTER_WIF_bm;
|
||||
} else
|
||||
/* If master read interrupt. */
|
||||
else if (currentStatus & TWI_MASTER_RIF_bm) {
|
||||
if (currentStatus & TWI_MASTER_RIF_bm) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
TWI_MasterReadHandler(twi);
|
||||
}
|
||||
|
||||
twi->interface->MASTER.STATUS =
|
||||
currentStatus
|
||||
| TWI_MASTER_RIF_bm;
|
||||
} else
|
||||
/* Bus went idle (timeout) */
|
||||
if( (currentStatus & TWI_MASTER_BUSSTATE_IDLE_gc)
|
||||
== TWI_MASTER_BUSSTATE_IDLE_gc ) {
|
||||
TWI_MasterTransactionFinished(twi, TWIM_RESULT_UNKNOWN);
|
||||
}
|
||||
/* If unexpected state. */
|
||||
else {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
TWI_MasterTransactionFinished(twi, TWIM_RESULT_FAIL);
|
||||
|
||||
twi->interface->MASTER.STATUS = currentStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,9 +349,9 @@ void TWI_MasterInterruptHandler(TWI_Master_t *twi)
|
||||
*
|
||||
* \param twi The TWI_Master_t struct instance.
|
||||
*/
|
||||
void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
|
||||
static void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
|
||||
{
|
||||
uint8_t currentStatus = twi->interface->MASTER.STATUS;
|
||||
uint8_t const currentStatus = twi->interface->MASTER.STATUS;
|
||||
|
||||
/* If bus error. */
|
||||
if (currentStatus & TWI_MASTER_BUSERR_bm) {
|
||||
@@ -297,9 +362,6 @@ void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
|
||||
twi->result = TWIM_RESULT_ARBITRATION_LOST;
|
||||
}
|
||||
|
||||
/* Clear interrupt flag. */
|
||||
twi->interface->MASTER.STATUS = currentStatus | TWI_MASTER_ARBLOST_bm;
|
||||
|
||||
twi->status = TWIM_STATUS_READY;
|
||||
}
|
||||
|
||||
@@ -310,36 +372,49 @@ void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
|
||||
*
|
||||
* \param twi The TWI_Master_t struct instance.
|
||||
*/
|
||||
void TWI_MasterWriteHandler(TWI_Master_t *twi)
|
||||
static void TWI_MasterWriteHandler(TWI_Master_t *twi)
|
||||
{
|
||||
/* Local variables used in if tests to avoid compiler warning. */
|
||||
uint8_t bytesToWrite = twi->bytesToWrite;
|
||||
uint8_t bytesToRead = twi->bytesToRead;
|
||||
uint8_t const bytesToWrite = twi->bytesToWrite;
|
||||
uint8_t const bytesToRead = twi->bytesToRead;
|
||||
|
||||
/* If NOT acknowledged (NACK) by slave cancel the transaction. */
|
||||
if (twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm) {
|
||||
if( twi->interface->MASTER.STATUS & TWI_MASTER_RXACK_bm ) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
|
||||
twi->result = TWIM_RESULT_NACK_RECEIVED;
|
||||
twi->status = TWIM_STATUS_READY;
|
||||
}
|
||||
|
||||
} else
|
||||
/* If more bytes to write, send data. */
|
||||
else if (twi->bytesWritten < bytesToWrite) {
|
||||
uint8_t data = twi->writeData[twi->bytesWritten];
|
||||
if( twi->bytesWritten < bytesToWrite ) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
uint8_t const data = twi->writeData[twi->bytesWritten];
|
||||
twi->interface->MASTER.DATA = data;
|
||||
++twi->bytesWritten;
|
||||
}
|
||||
|
||||
twi->bytesWritten++;
|
||||
} else
|
||||
/* If bytes to read, send repeated START condition + Address +
|
||||
* 'R/_W = 1'
|
||||
*/
|
||||
else if (twi->bytesRead < bytesToRead) {
|
||||
uint8_t readAddress = twi->address | 0x01;
|
||||
if( twi->bytesRead < bytesToRead ) {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
uint8_t const readAddress = twi->address | 0x01;
|
||||
twi->interface->MASTER.ADDR = readAddress;
|
||||
}
|
||||
|
||||
/* If transaction finished, send STOP condition and set RESULT OK. */
|
||||
else {
|
||||
#if 0
|
||||
PORTB.OUTSET = (1<<3);
|
||||
PORTB.OUTCLR = (1<<3);
|
||||
#endif
|
||||
twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
|
||||
TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
|
||||
}
|
||||
@@ -353,32 +428,36 @@ void TWI_MasterWriteHandler(TWI_Master_t *twi)
|
||||
*
|
||||
* \param twi The TWI_Master_t struct instance.
|
||||
*/
|
||||
void TWI_MasterReadHandler(TWI_Master_t *twi)
|
||||
static void TWI_MasterReadHandler(TWI_Master_t *twi)
|
||||
{
|
||||
#if 1
|
||||
PORTB.OUTTGL = (1<<3);
|
||||
PORTB.OUTTGL = (1<<3);
|
||||
#endif
|
||||
|
||||
/* Local variable used in if test to avoid compiler warning. */
|
||||
uint8_t const bytesToRead = twi->bytesToRead;
|
||||
|
||||
/* Fetch data if bytes to be read. */
|
||||
if (twi->bytesRead < TWIM_READ_BUFFER_SIZE) {
|
||||
uint8_t data = twi->interface->MASTER.DATA;
|
||||
if( twi->bytesRead < bytesToRead ) {
|
||||
uint8_t const data = twi->interface->MASTER.DATA;
|
||||
twi->readData[twi->bytesRead] = data;
|
||||
twi->bytesRead++;
|
||||
}
|
||||
|
||||
/* If buffer overflow, issue STOP and BUFFER_OVERFLOW condition. */
|
||||
else {
|
||||
twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
|
||||
TWI_MasterTransactionFinished(twi, TWIM_RESULT_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
/* Local variable used in if test to avoid compiler warning. */
|
||||
uint8_t bytesToRead = twi->bytesToRead;
|
||||
|
||||
/* If more bytes to read, issue ACK and start a byte read. */
|
||||
if (twi->bytesRead < bytesToRead) {
|
||||
if( twi->bytesRead < bytesToRead ) {
|
||||
twi->interface->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
|
||||
}
|
||||
|
||||
/* If transaction finished, issue NACK and STOP condition. */
|
||||
else {
|
||||
twi->interface->MASTER.CTRLC = TWI_MASTER_ACKACT_bm |
|
||||
twi->interface->MASTER.CTRLC = //TWI_MASTER_ACKACT_bm |
|
||||
TWI_MASTER_CMD_STOP_gc;
|
||||
TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
|
||||
}
|
||||
@@ -392,8 +471,9 @@ void TWI_MasterReadHandler(TWI_Master_t *twi)
|
||||
* \param twi The TWI_Master_t struct instance.
|
||||
* \param result The result of the operation.
|
||||
*/
|
||||
void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result)
|
||||
static void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result)
|
||||
{
|
||||
twi->result = result;
|
||||
twi->status = TWIM_STATUS_READY;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user