static u8 spi_readwrite(u32 spi, u8 data) { while (!(SPI_SR(spi) & SPI_SR_TXE)) ; SPI_DR(spi) = data; while (!(SPI_SR(spi) & SPI_SR_RXNE)) ; return SPI_DR(spi); }
/** * send 1 byte blocking * return 1 on success */ uint8_t spi_write_byte(uint8_t data){ while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); SPI_DR(Current_SPI) = data; while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); while(!(SPI_SR(Current_SPI) & SPI_SR_RXNE)); (void)SPI_DR(Current_SPI); while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); while(SPI_SR(Current_SPI) & SPI_SR_BSY); return 1; }
/* * Send a block of data via the SPI bus. */ static inline void SPISend(uint32_t base, const uint8_t *data, int len) { delay(1); for (int i = 0; i < len; i++) { spi_send(base, data[i]); } while (!(SPI_SR(base) & SPI_SR_TXE)) ; while ((SPI_SR(base) & SPI_SR_BSY)) ; }
void TBlockingSpiDmaJob::Run() { TaskId = TScheduler::GetCurrentTaskId(); CurrentJob = this; const uint32_t spi = FLASH_SPI_CHANNEL; const uint32_t dma = DMA1; assert(SPI_SR(spi) & SPI_SR_TXE); assert(~SPI_SR(spi) & SPI_SR_BSY); assert(!(SPI_SR(spi) & SPI_SR_RXNE)); { const uint32_t channel = FLASH_DMA_TX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(Out)); dma_set_number_of_data(dma, channel, Len); dma_set_read_from_memory(dma, channel); dma_enable_memory_increment_mode(dma, channel); dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); // dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } { const uint32_t channel = FLASH_DMA_RX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_number_of_data(dma, channel, Len); if (In != 0) { dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(In)); dma_enable_memory_increment_mode(dma, channel); } else { dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(&DummyPosition)); } dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } // Kick off the transfer spi_enable_rx_dma(spi); spi_enable_tx_dma(spi); // Wait for completion TScheduler::BlockUntil(&Finished); }
/** * Blocking rite data to current SPI * @param data - buffer with data * @param len - buffer length * @return 0 in case of error (or 1 in case of success) */ uint8_t spiWrite(uint8_t *data, uint16_t len){ uint16_t i; while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); for(i = 0; i < len; ++i){ SPI_DR(Current_SPI) = data[i]; while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); } while(!(SPI_SR(Current_SPI) & SPI_SR_RXNE)); (void)SPI_DR(Current_SPI); while(!(SPI_SR(Current_SPI) & SPI_SR_TXE)); while(SPI_SR(Current_SPI) & SPI_SR_BSY); return 1; }
uint8_t radio_read_single_reg(uint8_t reg) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_clear(R_CS_PORT, R_CS_PIN); spi_send8(R_SPI, reg & 0x7F); spi_read8(R_SPI); // Wait until send FIFO is empty while(SPI_SR(R_SPI) & SPI_SR_BSY); spi_send8(R_SPI, 0x0); while(SPI_SR(R_SPI) & SPI_SR_BSY); uint8_t out = spi_read8(R_SPI); gpio_set(R_CS_PORT, R_CS_PIN); return out; }
void radio_write_single_reg(uint8_t reg, uint8_t data) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_clear(R_CS_PORT, R_CS_PIN); spi_send8(R_SPI, reg | (1<<7)); spi_read8(R_SPI); // Wait until send FIFO is empty while(SPI_SR(R_SPI) & SPI_SR_BSY); spi_send8(R_SPI, data); spi_read8(R_SPI); // Wait until send FIFO is empty while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_set(R_CS_PORT, R_CS_PIN); }
static void radio_write_reg_start(uint8_t reg) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_clear(R_CS_PORT, R_CS_PIN); spi_send8(R_SPI, reg | (1<<7)); spi_read8(R_SPI); }
static void codecWriteReg(unsigned reg, unsigned value) { gpio_clear(GPIOA, GPIO4); spi_send(SPI1, (reg << 9) | value); while (!(SPI_SR(SPI1) & SPI_SR_TXE)); while (SPI_SR(SPI1) & SPI_SR_BSY); for (int i = 0; i < 100; i++) { __asm__("nop"); } gpio_set(GPIOA, GPIO4); for (int i = 0; i < 1000; i++) { __asm__("nop"); } }
void radio_read_burst_reg(uint8_t reg, uint8_t *buff, uint16_t len) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_clear(R_CS_PORT, R_CS_PIN); spi_send8(R_SPI, reg & 0x7F); spi_read8(R_SPI); // Wait until send FIFO is empty while(SPI_SR(R_SPI) & SPI_SR_BSY); uint16_t i; for ( i = 0; i < len; i++) { spi_send8(R_SPI, 0x0); while(SPI_SR(R_SPI) & SPI_SR_BSY); buff[i] = spi_read8(R_SPI); } gpio_set(R_CS_PORT, R_CS_PIN); }
void spi_send8(uint32_t spi, uint8_t data) { /* Wait for transfer finished. */ while (!(SPI_SR(spi) & SPI_SR_TXE)); /* Write data (8 or 16 bits, depending on DFF) into DR. */ SPI_DR8(spi) = data; }
uint8_t spi_read8(uint32_t spi) { /* Wait for transfer finished. */ while (!(SPI_SR(spi) & SPI_SR_RXNE)); /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ return SPI_DR8(spi); }
uint16_t spi_clean_disable(uint32_t spi) { /* Wait to receive last data */ while (!(SPI_SR(spi) & SPI_SR_RXNE)); uint16_t data = SPI_DR(spi); /* Wait to transmit last data */ while (!(SPI_SR(spi) & SPI_SR_TXE)); /* Wait until not busy */ while (SPI_SR(spi) & SPI_SR_BSY); SPI_CR1(spi) &= ~SPI_CR1_SPE; return data; }
int spi_transfer(spi_t spi, u16 data) { u32 r; while (!((r = SPI_SR(base_addr(spi))) & (SPI_SR_TXE | SPI_SR_ERROR))) ; if (r & SPI_SR_ERROR) return -SPI_TRANSFER_ERROR | r; SPI_DR(base_addr(spi)) = data; while (!((r = SPI_SR(base_addr(spi))) & (SPI_SR_RXNE | SPI_SR_ERROR))) ; if (r & SPI_SR_ERROR) return -SPI_TRANSFER_ERROR | r; return SPI_DR(base_addr(spi)); }
void radio_write_burst_reg(uint8_t reg, uint8_t *data, uint16_t len) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_clear(R_CS_PORT, R_CS_PIN); spi_send8(R_SPI, reg | (1<<7)); spi_read8(R_SPI); // Wait until send FIFO is empty uint16_t i = 0; for (i = 0; i < len; i++) { while(SPI_SR(R_SPI) & SPI_SR_BSY); spi_send8(R_SPI, data[i]); spi_read8(R_SPI); } // Wait until send FIFO is empty while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_set(R_CS_PORT, R_CS_PIN); }
uint16_t spi_xfer(uint32_t spi, uint16_t data) { spi_write(spi, data); /* Wait for transfer finished. */ while (!(SPI_SR(spi) & SPI_SR_RXNE)); /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ return SPI_DR(spi); }
void spi_exchange_nodma(const uint8_t *txbuf, uint8_t *rxbuf, size_t n) { uint8_t byte; const uint8_t *txptr = txbuf; uint8_t *rxptr = rxbuf; while (n-- > 0) { if (txptr) byte = *txptr++; else byte = 0xFF; while (!(SPI_SR(SPI2) & SPI_SR_TXE)); byte = (uint8_t)spi_xfer(SPI2, byte); if (rxptr) *rxptr++ = byte; } }
int spi_get_interrupt_status(spi_t spi, int interrupt) { return SPI_SR(base_addr(spi)) & interrupt; }
bool TSpiDmaQueue::TryStartJob() { // Start the next DMA job in the queue if the SPI interface is // available (TXE=1 and BSY=0) // We treat both SPI busses (flash and display) as one, so no concurrent jobs // are allowed. const uint32_t spi = LCD_SPI_CHANNEL; if ((SPI_SR(spi) & SPI_SR_TXE) && (~SPI_SR(spi) & SPI_SR_BSY)) { if (Jobs.Empty()) { return false; } const TSpiDmaJob& job = Jobs.First(); const TBuffer& buffer = job.GetBuffer(); // SPI receive register should be empty here! assert(!(SPI_SR(spi) & SPI_SR_RXNE)); const uint32_t dma = DMA1; { const uint32_t channel = (job.GetChip() == TSpiDmaJob::CS_LCD) ? LCD_DMA_TX_CHANNEL : FLASH_DMA_TX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(buffer.GetData())); dma_set_number_of_data(dma, channel, buffer.GetLength()); dma_set_read_from_memory(dma, channel); dma_enable_memory_increment_mode(dma, channel); dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); //dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } { const uint32_t channel = (job.GetChip() == TSpiDmaJob::CS_LCD) ? LCD_DMA_RX_CHANNEL : FLASH_DMA_RX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(buffer.GetData())); dma_set_number_of_data(dma, channel, buffer.GetLength()); dma_enable_memory_increment_mode(dma, channel); dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } // Set CS and LCD_A0 lines Pin_lcd_cs.Clear(); if (job.GetLcdData()) { Pin_lcd_a0.Set(); } else { Pin_lcd_a0.Clear(); } // Kick off the transfer spi_enable_rx_dma(spi); spi_enable_tx_dma(spi); return true; } return false; }
static int spi_dma_transceive(uint8_t *tx_buf, int tx_len, uint8_t *rx_buf, int rx_len) #endif { /* Check for 0 length in both tx and rx */ if ((rx_len < 1) && (tx_len < 1)) { /* return -1 as error */ return -1; } /* Reset DMA channels*/ dma_channel_reset(DMA1, DMA_CHANNEL2); dma_channel_reset(DMA1, DMA_CHANNEL3); /* Reset SPI data and status registers. * Here we assume that the SPI peripheral is NOT * busy any longer, i.e. the last activity was verified * complete elsewhere in the program. */ volatile uint8_t temp_data __attribute__ ((unused)); while (SPI_SR(SPI1) & (SPI_SR_RXNE | SPI_SR_OVR)) { temp_data = SPI_DR(SPI1); } /* Reset status flag appropriately (both 0 case caught above) */ transceive_status = NONE; if (rx_len < 1) { transceive_status = ONE; } /* Determine tx length case to change behaviour * If tx_len >= rx_len, then normal case, run both DMAs with normal settings * If rx_len == 0, just don't run the rx DMA at all * If tx_len == 0, use a dummy buf and set the tx dma to transfer the same * amount as the rx_len, to ensure everything is clocked in * If 0 < tx_len < rx_len, first do a normal case, then on the tx finished * interrupt, set up a new dummyy buf tx dma transfer for the remaining * required clock cycles (handled in tx dma complete interrupt) */ if ((tx_len > 0) && (tx_len < rx_len)) { rx_buf_remainder = rx_len - tx_len; } /* Set up rx dma, note it has higher priority to avoid overrun */ if (rx_len > 0) { dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t)&SPI1_DR); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t)rx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL2, rx_len); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_VERY_HIGH); } /* Set up tx dma (must always run tx to get clock signal) */ if (tx_len > 0) { /* Here we have a regular tx transfer */ dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&SPI1_DR); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)tx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL3, tx_len); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); } else { /* Here we aren't transmitting any real data, use the dummy buffer * and set the length to the rx_len to get all rx data in, while * not incrementing the memory pointer */ dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&SPI1_DR); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)(&dummy_tx_buf)); // Change here dma_set_number_of_data(DMA1, DMA_CHANNEL3, rx_len); // Change here dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL3); // Change here #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); } /* Enable dma transfer complete interrupts */ if (rx_len > 0) { dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); } dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); /* Activate dma channels */ if (rx_len > 0) { dma_enable_channel(DMA1, DMA_CHANNEL2); } dma_enable_channel(DMA1, DMA_CHANNEL3); /* Enable the spi transfer via dma * This will immediately start the transmission, * after which when the receive is complete, the * receive dma will activate */ if (rx_len > 0) { spi_enable_rx_dma(SPI1); } spi_enable_tx_dma(SPI1); return 0; }
void spi_clear_interrupt(spi_t spi, int interrupt) { /* CRC error */ SPI_SR(base_addr(spi)) &= ~interrupt; }
int main(void) { int counter_tx = 0; int counter_rx = 0; cnt_state counter_state = TX_UP_RX_HOLD; int i = 0; /* Transmit and Receive packets, set transmit to index and receive to known unused value to aid in debugging */ #if USE_16BIT_TRANSFERS uint16_t tx_packet[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; uint16_t rx_packet[16] = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42}; #else uint8_t tx_packet[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; uint8_t rx_packet[16] = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42}; #endif transceive_status = DONE; clock_setup(); gpio_setup(); usart_setup(); usart_print_string("SPI-DMA Test\n\r"); spi_setup(); dma_setup(); /* Blink the LED (PA8) on the board with every transmitted byte. */ while (1) { /* LED on/off */ gpio_toggle(GPIOA, GPIO1); /* Print what is going to be sent on the SPI bus */ usart_print_string("Sending packet (tx len: "); usart_print_int(counter_tx); usart_print_string(")\n\r"); for (i = 0; i < counter_tx; i++) { usart_print_int(tx_packet[i]); usart_print_string(" "); } usart_print_string("\r\n"); /* Start a transceive */ if (spi_dma_transceive(tx_packet, counter_tx, rx_packet, counter_rx)) { usart_print_string("Attempted 0 length tx and rx packets\r\n"); } /* Wait until transceive complete. * This checks the state flag as well as follows the * procedure on the Reference Manual (RM0008 rev 14 * Section 25.3.9 page 692, the note.) */ while (transceive_status != DONE) ; while (!(SPI_SR(SPI2) & SPI_SR_TXE)) ; while (SPI_SR(SPI2) & SPI_SR_BSY) ; /* Print what was received on the SPI bus */ usart_print_string("Received Packet (rx len "); usart_print_int(counter_rx); usart_print_string(")\n\r"); for (i = 0; i < 16; i++) { usart_print_int(rx_packet[i]); usart_print_string(" "); } usart_print_string("\r\n\r\n"); /* Update counters * If we use the loopback method, we can not * have a rx length longer than the tx length. * Testing rx lengths longer than tx lengths * requires an actual slave device that will * return data. */ switch (counter_state) { case TX_UP_RX_HOLD: counter_tx++; if (counter_tx > 15) { counter_state = TX_HOLD_RX_UP; } break; case TX_HOLD_RX_UP: counter_rx++; if (counter_rx > 15) { counter_state = TX_DOWN_RX_DOWN; } break; case TX_DOWN_RX_DOWN: counter_tx--; counter_rx--; if (counter_tx < 1) { counter_state = TX_UP_RX_HOLD; } break; default: ; } /* Reset receive buffer for consistency */ for (i = 0; i < 16; i++) { rx_packet[i] = 0x42; } } return 0; }
static int spi_dma_transceive(uint8_t *tx_buf, int tx_len, uint8_t *rx_buf, int rx_len) #endif { /* Check for 0 length in both tx and rx */ if ((rx_len < 1) && (tx_len < 1)) { /* return -1 as error */ return -1; } /* Reset DMA channels*/ dma_channel_reset(DMA1, DMA_CHANNEL4); dma_channel_reset(DMA1, DMA_CHANNEL5); /* Reset SPI data and status registers. * Here we assume that the SPI peripheral is NOT * busy any longer, i.e. the last activity was verified * complete elsewhere in the program. */ volatile uint8_t temp_data __attribute__ ((unused)); while (SPI_SR(SPI2) & (SPI_SR_RXNE | SPI_SR_OVR)) { temp_data = SPI_DR(SPI2); } /* Reset status flag appropriately (both 0 case caught above) */ transceive_status = NONE; if (rx_len < 1) { transceive_status = ONE; } if (tx_len < 1) { transceive_status = ONE; } /* Set up rx dma, note it has higher priority to avoid overrun */ if (rx_len > 0) { dma_set_peripheral_address(DMA1, DMA_CHANNEL4, (uint32_t)&SPI2_DR); dma_set_memory_address(DMA1, DMA_CHANNEL4, (uint32_t)rx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL4, rx_len); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL4); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL4); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL4, DMA_CCR_PL_VERY_HIGH); } /* Set up tx dma */ if (tx_len > 0) { dma_set_peripheral_address(DMA1, DMA_CHANNEL5, (uint32_t)&SPI2_DR); dma_set_memory_address(DMA1, DMA_CHANNEL5, (uint32_t)tx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL5, tx_len); dma_set_read_from_memory(DMA1, DMA_CHANNEL5); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL5); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL5, DMA_CCR_PL_HIGH); } /* Enable dma transfer complete interrupts */ if (rx_len > 0) { dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4); } if (tx_len > 0) { dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL5); } /* Activate dma channels */ if (rx_len > 0) { dma_enable_channel(DMA1, DMA_CHANNEL4); } if (tx_len > 0) { dma_enable_channel(DMA1, DMA_CHANNEL5); } /* Enable the spi transfer via dma * This will immediately start the transmission, * after which when the receive is complete, the * receive dma will activate */ if (rx_len > 0) { spi_enable_rx_dma(SPI2); } if (tx_len > 0) { spi_enable_tx_dma(SPI2); } return 0; }
static void radio_write_reg_end(void) { while(SPI_SR(R_SPI) & SPI_SR_BSY); gpio_set(R_CS_PORT, R_CS_PIN); }
static void radio_write_reg_continuing(uint8_t data) { while(SPI_SR(R_SPI) & SPI_SR_BSY); spi_send8(R_SPI, data); spi_read8(R_SPI); }