Better error information

This commit is contained in:
Jeremy Soller
2019-11-13 15:40:53 -07:00
parent b1d0aaf180
commit 77aa419318

View File

@ -5,7 +5,7 @@
#include <ec/smbus.h>
//TODO: find best value
#define TIMEOUT (F_CPU/1000)
#define I2C_TIMEOUT (F_CPU/1000)
#define HOSTA_BYTE_DONE (1 << 7)
#define HOSTA_TIMEOUT (1 << 6)
@ -18,10 +18,12 @@
#define HOSTA_ERR (HOSTA_TIMEOUT | HOSTA_NACK | HOSTA_FAIL | HOSTA_BUS_ERR | HOSTA_DEV_ERR)
void i2c_reset(bool kill) {
// Set kill bit
if (kill) HOCTLA |= (1 << 1);
// Wait for host to finish
while (HOSTAA & HOSTA_BUSY) {}
if (HOSTAA & HOSTA_BUSY) {
// Set kill bit
if (kill) HOCTLA |= (1 << 1);
// Wait for host to finish
while (HOSTAA & HOSTA_BUSY) {}
}
// Clear status register
HOSTAA = HOSTAA;
// Clear current command
@ -39,9 +41,6 @@ int i2c_start(uint8_t addr, bool read) {
if (read) {
// Enable direction switch
HOCTL2A |= (1 << 3) | (1 << 2);
// Clear status to start switch process
HOSTAA = HOSTAA;
} else {
// Unsupported!
i2c_reset(true);
@ -49,6 +48,8 @@ int i2c_start(uint8_t addr, bool read) {
}
}
} else {
i2c_reset(true);
// Enable host controller with i2c compatibility
HOCTL2A = (1 << 1) | 1;
@ -86,35 +87,37 @@ static int i2c_transaction(uint8_t * data, int length, bool read) {
if (HOSTAA & HOSTA_BYTE_DONE) {
// Clear status to process next byte
HOSTAA = HOSTAA;
} else
} else {
// Start new transaction
HOCTLA = (1 << 6) | (0b111 << 2) | 1;
}
// If we are waiting on direction switch
if (HOCTL2A & (1 << 2)) {
// Complete direction switch
HOCTL2A &= ~(1 << 2);
} else {
// Start new transaction
HOCTLA = (1 << 6) | (0b111 << 2);
}
// Wait for byte done, timeout, or error
// uint32_t timeout;
// for(timeout = TIMEOUT; timeout > 0; timeout--) {
for(;;) {
uint8_t status = HOSTAA;
if (status & HOSTA_BYTE_DONE) {
// If byte is finished, break
break;
} else if (status & HOSTA_ERR) {
// If error occured, kill transaction and return error
uint8_t status;
uint32_t timeout = I2C_TIMEOUT;
for(timeout = I2C_TIMEOUT; timeout > 0; timeout--) {
status = HOSTAA;
// If error occured, kill transaction and return error
if (status & HOSTA_ERR) {
i2c_reset(true);
return -(int)(status & HOSTA_ERR);
return -(int)(status);
} else
// If byte done, break
if (status & HOSTA_BYTE_DONE) {
break;
}
}
// if (timeout == 0) {
// // If timeout occured, kill transaction and return error
// i2c_reset(true);
// return -1;
// }
// If timeout occured, kill transaction and return error
if (timeout == 0) {
i2c_reset(true);
return -(0x1000 | (int)status);
}
if (read) {
// Read byte