/** * \brief Interrupt handler for the SPI slave. */ void SPI_IrqHandler( void ) { uint32_t status; uint8_t startNew = 0; status = SPI_GetStatus( SPI_SLAVE_BASE ) ; if ( status & SPI_SR_NSSR ) { if ( status & SPI_SR_RXBUFF ) { /* Disable the RX and TX PDC transfer requests */ SPI_PdcDisableTx( SPI_SLAVE_BASE ) ; SPI_PdcDisableRx( SPI_SLAVE_BASE ) ; } if ( status & SPI_IDR_ENDRX ) { SPI_DisableIt( SPI_SLAVE_BASE, SPI_IDR_ENDRX ) ; } switch ( status & (SPI_SR_RXBUFF | SPI_SR_ENDRX) ) { case (SPI_SR_RXBUFF | SPI_SR_ENDRX): case (SPI_SR_RXBUFF): SpiSlaveCommandProcess() ; startNew = 1 ; break ; /* Maybe command break data transfer, start new */ case SPI_SR_ENDRX: { /* Command breaks data transfer */ SPI_PdcDisableTx( SPI_SLAVE_BASE ) ; SPI_PdcDisableRx( SPI_SLAVE_BASE ) ; SPI_Configure( SPI_SLAVE_BASE, ID_SPI, 0 ) ; SPI_ConfigureNPCS( SPI_SLAVE_BASE, 0 , 0 ) ; startNew = 1 ; } break; default: break; } if ( startNew ) { if ( spiCmd != CMD_END ) { spiStatus.cmdList[spiStatus.totalNumCommands] = spiCmd; spiStatus.totalNumCommands ++; } SpiSlaveNewCommand(); } } }
/** * \brief Initialize SPI as slave */ static void SpiSlaveInitialize( void ) { uint32_t i ; printf("-I- Initialize SPI as slave ...\n\r"); /* Configures a SPI peripheral */ SPI_Configure(SPI_SLAVE_BASE, ID_SPI, 0); SPI_ConfigureNPCS(SPI_SLAVE_BASE, 0 , 0); /* Disable the RX and TX PDC transfer requests */ SPI_PdcDisableTx(SPI_MASTER_BASE); SPI_PdcDisableRx(SPI_MASTER_BASE); /* Enables a SPI peripheral. */ SPI_Enable(SPI_SLAVE_BASE); /* Reset status */ spiStatus.totalNumBlocks = 0; spiStatus.totalNumCommands = 0; for ( i = 0; i < NB_STATUS_CMD; i++ ) { spiStatus.cmdList[i] = 0 ; } /* Start waiting command */ spiState = SLAVE_STATE_IDLE; spiCmd = RC_SYN; SpiSlaveTransfer(&spiCmd, 4, 0, 0); }
/** * \brief Initialize SPI as master */ static void SpiMasterInitialize( void ) { printf( "-I- Configure SPI as master\n\r" ) ; /* Master mode */ SPI_Configure( SPI_MASTER_BASE, ID_SPI, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS( 0 ) ) ; SPI_ConfigureNPCS( SPI_MASTER_BASE, 0, SPI_DLYBCT( 100000, BOARD_MCK ) | SPI_DLYBS(100000, BOARD_MCK) | SPI_SCBR( spiClock, BOARD_MCK) ) ; /* Disable the RX and TX PDC transfer requests */ SPI_PdcDisableTx( SPI_MASTER_BASE ) ; SPI_PdcDisableRx( SPI_MASTER_BASE ) ; /* Enables a SPI peripheral. */ SPI_Enable( SPI_MASTER_BASE ) ; }
/** * \brief Perform SPI master transfer using PDC. * \param pBuf Pointer to 1st buffer to transfer. * \param size Size of the 1st buffer. * \param pNextBuf Pointer to 2nd buffer to transfer. * \param nextSize Size of the 2nd buffer. */ static void SpiMasterTransfer( void * pBuf, uint16_t size, void * pNextBuf, uint16_t nextSize ) { SPI_PdcSetTx(SPI_MASTER_BASE, pBuf, size, pNextBuf, nextSize); SPI_PdcSetRx(SPI_MASTER_BASE, pBuf, size, pNextBuf, nextSize); /* Enable the RX and TX PDC transfer requests */ SPI_PdcEnableRx(SPI_MASTER_BASE); SPI_PdcEnableTx(SPI_MASTER_BASE); /* Waiting transfer done*/ while((SPI_GetStatus(SPI_MASTER_BASE)& SPI_SR_RXBUFF) == 0); /* Disable the RX and TX PDC transfer requests */ SPI_PdcDisableTx(SPI_MASTER_BASE); SPI_PdcDisableRx(SPI_MASTER_BASE); }
void spi_stack_slave_init(void) { PIO_Configure(spi_slave_pins, PIO_LISTSIZE(spi_slave_pins)); // Configure SPI interrupts for Slave NVIC_DisableIRQ(SPI_IRQn); NVIC_ClearPendingIRQ(SPI_IRQn); NVIC_SetPriority(SPI_IRQn, PRIORITY_STACK_SLAVE_SPI); NVIC_EnableIRQ(SPI_IRQn); // Configure SPI peripheral SPI_Configure(SPI, ID_SPI, 0); SPI_ConfigureNPCS(SPI, 0 , 0); // Disable RX and TX DMA transfer requests SPI_PdcDisableTx(SPI); SPI_PdcDisableRx(SPI); // Enable SPI peripheral SPI_Enable(SPI); // Call interrupt on data in rx buffer SPI_EnableIt(SPI, SPI_IER_RDRF); }