spiClient_t *spiClientInit(SPI_TypeDef *spi, uint16_t baud, GPIO_TypeDef *csPort, uint16_t csPin, volatile uint32_t *flag, spiCallback_t *callback) { spiClient_t *client; client = (spiClient_t *)aqCalloc(1, sizeof(spiClient_t)); #ifdef SPI_SPI1_CLOCK if (spi == SPI1) { client->interface = 0; spi1Init(); } #endif #ifdef SPI_SPI2_CLOCK if (spi == SPI2) { client->interface = 1; spi2Init(); } #endif #ifdef SPI_SPI3_CLOCK if (spi == SPI3) { client->interface = 2; spi3Init(); } #endif client->cs = digitalInit(csPort, csPin, 1); spiDeselect(client); spiChangeBaud(client, baud); client->flag = flag; client->callback = callback; return client; }
static inline bool cdeselect(void) { spiDeselect(); // spi_disable(); nRF905_interrupt_on(); return false; }
void spi_transfer(uint8_t *buf, uint16_t len, uint8_t toggle_cs) { spiSelect (SS_PB2); spiMultiByteTransfer(buf, len); if (toggle_cs) spiDeselect (SS_PB2); return; }
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); }
void nRF905_init() { #ifdef ARDUINO pinMode(TRX_EN, OUTPUT); pinMode(PWR_MODE, OUTPUT); pinMode(TX_EN, OUTPUT); #if NRF905_COLLISION_AVOID pinMode(CD, INPUT); #endif #if AM_IS_USED_HW pinMode(AM, INPUT); #endif #if !NRF905_DR_SW pinMode(DR, INPUT); #endif digitalWrite(CSN, HIGH); pinMode(CSN, OUTPUT); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV2); #else TRX_EN_DDR |= _BV(TRX_EN_BIT); PWR_MODE_DDR |= _BV(PWR_MODE_BIT); TX_EN_DDR |= _BV(TX_EN_BIT); #if NRF905_COLLISION_AVOID CD_DDR &= ~_BV(CD_BIT); #endif #if AM_IS_USED_HW AM_DDR &= ~_BV(AM_BIT); #endif #if !NRF905_DR_SW DR_DDR &= ~_BV(DR_BIT); #endif spiDeselect(); CSN_DDR |= _BV(CSN_BIT); spi_init(); #endif radio.state = NRF905_RADIO_STATE_IDLE; // Startup enableStandbyMode(); receiveMode(); nRF905_powerDown(); _delay_ms(3); defaultConfig(); #if NRF905_INTERRUPTS // Set interrupts REG_EXTERNAL_INT_CTL |= BIT_EXTERNAL_INT_CTL; nRF905_interrupt_on(); #endif nRF905_powerUp(); }