static void spiStartTxn(spiStruct_t *interface) { spiSlot_t *slot = &interface->slots[interface->tail]; spiClient_t *client = slot->client; uint32_t tmp; // is the current txn taking too long? if (interface->txRunning != 0 && (timerMicros() - interface->txnStart) > SPI_MAX_TXN_TIME) { spiDisableDMA(interface); spiDisableSPI(interface); spiDeselect(client); interface->tail = (interface->tail + 1) % SPI_SLOTS; slot = &interface->slots[interface->tail]; client = slot->client; interface->txRunning = 0; interface->txnTimeouts++; } if (interface->tail != interface->head && interface->txRunning == 0) { interface->txRunning = 1; interface->txnStart = timerMicros(); // set baud rate tmp = interface->spi->CR1 & SPI_BAUD_MASK; tmp |= client->baud; interface->spi->CR1 = tmp; // clear DR SPI_I2S_ReceiveData(interface->spi); spiSelect(client); // specify "in transaction" if (client->flag) *client->flag = 0; interface->rxDMAStream->M0AR = slot->rxBuf; interface->rxDMAStream->NDTR = slot->size; DMA_Cmd(interface->rxDMAStream, ENABLE); interface->txDMAStream->M0AR = slot->txBuf; interface->txDMAStream->NDTR = slot->size; DMA_Cmd(interface->txDMAStream, ENABLE); SPI_Cmd(interface->spi, ENABLE); } }
static void spiEndTxn(spiStruct_t *interface) { uint8_t tail = interface->tail; spiClient_t *client = interface->slots[tail].client; uint32_t tmp; spiDisableSPI(interface); spiDisableDMA(interface); spiDeselect(client); // record longest txn tmp = timerMicros() - interface->txnStart; if (tmp > interface->txnMaxTime) interface->txnMaxTime = tmp; spiNotify(client); tail = (tail + 1) % SPI_SLOTS; interface->tail = tail; interface->txRunning = 0; spiTriggerSchedule(client->interface); }