Skip to content

Commit

Permalink
[SPI] Fix SPI nanosecond timing
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalentity committed Nov 7, 2020
1 parent e72e702 commit 85ae3b2
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 93 deletions.
30 changes: 12 additions & 18 deletions src/main/drivers/bus_busdev_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,13 @@ bool spiBusTransfer(const busDevice_t * dev, uint8_t * rxBuf, const uint8_t * tx
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
spiChipSelectSetupDelay();
spiBusSelectDevice(dev);
}

spiTransfer(instance, rxBuf, txBuf, length);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
spiChipSelectHoldTime();
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand All @@ -97,17 +95,15 @@ bool spiBusTransferMultiple(const busDevice_t * dev, busTransferDescriptor_t * d
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
spiChipSelectSetupDelay();
spiBusSelectDevice(dev);
}

for (int n = 0; n < count; n++) {
spiTransfer(instance, dsc[n].rxBuf, dsc[n].txBuf, dsc[n].length);
}

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
spiChipSelectHoldTime();
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand All @@ -118,16 +114,14 @@ bool spiBusWriteRegister(const busDevice_t * dev, uint8_t reg, uint8_t data)
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
delayMicroseconds(1);
spiBusSelectDevice(dev);
}

spiTransferByte(instance, reg);
spiTransferByte(instance, data);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
delayMicroseconds(1);
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand All @@ -138,14 +132,14 @@ bool spiBusWriteBuffer(const busDevice_t * dev, uint8_t reg, const uint8_t * dat
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
spiBusSelectDevice(dev);
}

spiTransferByte(instance, reg);
spiTransfer(instance, NULL, data, length);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand All @@ -156,14 +150,14 @@ bool spiBusReadBuffer(const busDevice_t * dev, uint8_t reg, uint8_t * data, uint
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
spiBusSelectDevice(dev);
}

spiTransferByte(instance, reg);
spiTransfer(instance, data, NULL, length);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand All @@ -174,14 +168,14 @@ bool spiBusReadRegister(const busDevice_t * dev, uint8_t reg, uint8_t * data)
SPI_TypeDef * instance = spiInstanceByDevice(dev->busdev.spi.spiBus);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOLo(dev->busdev.spi.csnPin);
spiBusSelectDevice(dev);
}

spiTransferByte(instance, reg);
spiTransfer(instance, data, NULL, 1);

if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) {
IOHi(dev->busdev.spi.csnPin);
spiBusDeselectDevice(dev);
}

return true;
Expand Down
41 changes: 20 additions & 21 deletions src/main/drivers/bus_i2c_stm32f30x.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static void i2cResetInterface(i2cBusState_t * i2cBusState)
i2cErrorCount++;
}

static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentTicks)
static void i2cStateMachine(i2cBusState_t * i2cBusState, const timeUs_t currentTicksUs)
{
I2C_TypeDef * I2Cx = i2cHardwareMap[i2cBusState->device].dev;

Expand All @@ -137,7 +137,7 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
i2cBusState->state = I2C_STATE_STOPPED;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;
Expand All @@ -147,7 +147,7 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
break;

case I2C_STATE_STARTING:
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
i2cBusState->state = I2C_STATE_STARTING_WAIT;
FALLTHROUGH;

Expand All @@ -166,7 +166,7 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
i2cBusState->state = I2C_STATE_W_ADDR;
}
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;
Expand All @@ -175,7 +175,7 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
I2C_TransferHandling(I2Cx, i2cBusState->addr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
i2cBusState->state = I2C_STATE_R_ADDR_WAIT;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
FALLTHROUGH;

case I2C_STATE_R_ADDR_WAIT:
Expand All @@ -185,15 +185,15 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
else if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_NACKF) != RESET) {
i2cBusState->state = I2C_STATE_NACK;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;

case I2C_STATE_R_REGISTER:
I2C_SendData(I2Cx, i2cBusState->reg);
i2cBusState->state = I2C_STATE_R_REGISTER_WAIT;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
FALLTHROUGH;

case I2C_STATE_R_REGISTER_WAIT:
Expand All @@ -209,15 +209,15 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
else if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_NACKF) != RESET) {
i2cBusState->state = I2C_STATE_NACK;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;

case I2C_STATE_R_RESTARTING:
I2C_TransferHandling(I2Cx, i2cBusState->addr, i2cBusState->len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
i2cBusState->state = I2C_STATE_R_TRANSFER;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
FALLTHROUGH;

case I2C_STATE_R_TRANSFER:
Expand All @@ -231,9 +231,9 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
i2cBusState->state = I2C_STATE_STOPPING;
}

i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;
Expand All @@ -244,12 +244,12 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
// Special no-address case, skip address byte transmission
I2C_TransferHandling(I2Cx, i2cBusState->addr, i2cBusState->len, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
i2cBusState->state = I2C_STATE_W_TRANSFER;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
}
else {
I2C_TransferHandling(I2Cx, i2cBusState->addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
i2cBusState->state = I2C_STATE_W_ADDR_WAIT;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
}
break;

Expand All @@ -260,15 +260,15 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
else if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_NACKF) != RESET) {
i2cBusState->state = I2C_STATE_NACK;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;

case I2C_STATE_W_REGISTER:
I2C_SendData(I2Cx, i2cBusState->reg);
i2cBusState->state = I2C_STATE_W_REGISTER_WAIT;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
FALLTHROUGH;

case I2C_STATE_W_REGISTER_WAIT:
Expand All @@ -284,15 +284,15 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
else if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_NACKF) != RESET) {
i2cBusState->state = I2C_STATE_NACK;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}
break;

case I2C_STATE_W_RESTARTING:
I2C_TransferHandling(I2Cx, i2cBusState->addr, i2cBusState->len, I2C_AutoEnd_Mode, I2C_No_StartStop);
i2cBusState->state = I2C_STATE_W_TRANSFER;
i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
FALLTHROUGH;

case I2C_STATE_W_TRANSFER:
Expand All @@ -306,9 +306,9 @@ static void i2cStateMachine(i2cBusState_t * i2cBusState, const uint32_t currentT
i2cBusState->state = I2C_STATE_STOPPING;
}

i2cBusState->timeout = currentTicks;
i2cBusState->timeout = currentTicksUs;
}
else if (ticks_diff_us(i2cBusState->timeout, currentTicks) >= I2C_TIMEOUT) {
else if ((currentTicksUs - i2cBusState->timeout) >= I2C_TIMEOUT) {
i2cBusState->state = I2C_STATE_BUS_ERROR;
}

Expand Down Expand Up @@ -399,8 +399,7 @@ uint16_t i2cGetErrorCounter(void)
static void i2cWaitForCompletion(I2CDevice device)
{
do {
const uint32_t currentTicks = ticks();
i2cStateMachine(&busState[device], currentTicks);
i2cStateMachine(&busState[device], micros());
} while (busState[device].state != I2C_STATE_STOPPED);
}

Expand Down

0 comments on commit 85ae3b2

Please sign in to comment.