Skip to content

Commit

Permalink
[VIDORBL] Add timeouts to i2c operations
Browse files Browse the repository at this point in the history
  • Loading branch information
facchinm committed Aug 29, 2018
1 parent e66adea commit d4c7854
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 11 deletions.
27 changes: 24 additions & 3 deletions bootloaders/zero/board_driver_i2c.c
Expand Up @@ -246,24 +246,34 @@ static inline void prepareAckBitWIRE( void )
I2C_SERCOM->I2CM.CTRLB.bit.ACKACT = 0;
}

static inline void prepareCommandBitsWire(uint8_t cmd)
static inline int prepareCommandBitsWire(uint8_t cmd)
{
I2C_SERCOM->I2CM.CTRLB.bit.CMD = cmd;

int timeout = 50000;
while(I2C_SERCOM->I2CM.SYNCBUSY.bit.SYSOP)
{
if (timeout -- < 0) {
return -1;
}
// Waiting for synchronization
}
return 0;
}

static inline bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag)
{
// 7-bits address + 1-bits R/W
address = (address << 0x1ul) | flag;

int timeout = 50000;

// Wait idle or owner bus mode
while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
while ( !isBusIdleWIRE() && !isBusOwnerWIRE() ) {
if (timeout -- < 0) {
return false;
}
}

// Send start and address
I2C_SERCOM->I2CM.ADDR.bit.ADDR = address;
Expand All @@ -273,13 +283,19 @@ static inline bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFla
{
while( !I2C_SERCOM->I2CM.INTFLAG.bit.MB )
{
if (timeout -- < 0) {
return false;
}
// Wait transmission complete
}
}
else // Read mode
{
while( !I2C_SERCOM->I2CM.INTFLAG.bit.SB )
{
if (timeout -- < 0) {
return false;
}
// If the slave NACKS the address, the MB bit will be set.
// In that case, send a stop condition and return false.
if (I2C_SERCOM->I2CM.INTFLAG.bit.MB) {
Expand Down Expand Up @@ -310,9 +326,14 @@ static inline bool sendDataMasterWIRE(uint8_t data)
//Send data
I2C_SERCOM->I2CM.DATA.bit.DATA = data;

int timeout = 50000;

//Wait transmission successful
while(!I2C_SERCOM->I2CM.INTFLAG.bit.MB) {

if (timeout -- < 0) {
return false;
}
// If a bus error occurs, the MB bit may never be set.
// Check the bus error bit and bail if it's set.
if (I2C_SERCOM->I2CM.STATUS.bit.BUSERR) {
Expand Down Expand Up @@ -410,7 +431,7 @@ uint8_t i2c_endTransmission(bool stopBit)
txBufferLen--;
}
}

if (stopBit)
{
prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
Expand Down
24 changes: 17 additions & 7 deletions bootloaders/zero/board_driver_pmic.c
Expand Up @@ -27,7 +27,10 @@ extern uint8_t rxBuffer[1];
uint8_t readRegister(uint8_t reg) {
i2c_beginTransmission(PMIC_ADDRESS);
i2c_write(reg);
i2c_endTransmission(true);
int ret = i2c_endTransmission(true);
if (ret != 0) {
return 0;
}

i2c_requestFrom(PMIC_ADDRESS, 1, true);
return rxBuffer[0];
Expand All @@ -44,8 +47,11 @@ uint8_t writeRegister(uint8_t reg, uint8_t data) {

bool disableWatchdog(void) {
uint8_t DATA = readRegister(CHARGE_TIMER_CONTROL_REGISTER);
if (DATA == 0) {
return false;
}
writeRegister(CHARGE_TIMER_CONTROL_REGISTER, (DATA & 0b11001110));
return 1;
return true;
}

bool setInputVoltageLimit(uint16_t voltage) {
Expand Down Expand Up @@ -217,22 +223,26 @@ bool disableCharge()
return 1;
}

void apply_pmic_newdefaults()
int apply_pmic_newdefaults()
{
disableWatchdog();
if (!disableWatchdog()) {
return -1;
}

//disableDPDM();
disableCharge();
setInputVoltageLimit(4360); // default
setInputCurrentLimit(2000); // 2A
setInputCurrentLimit(3000); // 2A
setChargeCurrent(0,0,0,0,0,0); // 512mA
setChargeVoltage(4112); // 4.112V termination voltage
i2c_end();
return 0;
}

void configure_pmic()
int configure_pmic()
{
i2c_init(100000);
apply_pmic_newdefaults();
return apply_pmic_newdefaults();
}

#endif
2 changes: 1 addition & 1 deletion bootloaders/zero/board_driver_pmic.h
Expand Up @@ -40,6 +40,6 @@
#define FAULT_REGISTER 0x09
#define PMIC_VERSION_REGISTER 0x0A

void configure_pmic();
int configure_pmic();

#endif // _BOARD_DRIVER_PMIC_

0 comments on commit d4c7854

Please sign in to comment.