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