void spi_stack_master_enable_dma(void) { transceive_state = TRANSCEIVE_STATE_BUSY; spi_stack_select(stack_address_current); spi_stack_master_reset_recv_dma_buffer(); spi_stack_master_reset_send_dma_buffer(); SPI_EnableIt(SPI, SPI_IER_ENDRX | SPI_IER_ENDTX); SPI->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN; }
/** * \brief Perform SPI slave 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 SpiSlaveTransfer( void* pBuf, uint16_t size, void* pNextBuf, uint16_t nextSize ) { uint32_t spiIER ; SPI_PdcSetTx( SPI_SLAVE_BASE, pBuf, size, pNextBuf, nextSize ) ; SPI_PdcSetRx( SPI_SLAVE_BASE, pBuf, size, pNextBuf, nextSize ) ; /* Enable the RX and TX PDC transfer requests */ SPI_PdcEnableRx( SPI_SLAVE_BASE ) ; SPI_PdcEnableTx( SPI_SLAVE_BASE ) ; /* Transfer done handler is in ISR ... */ spiIER = SPI_IER_NSSR | SPI_IER_RXBUFF | (pNextBuf ? SPI_IER_ENDRX : 0) ; SPI_EnableIt( SPI_SLAVE_BASE, spiIER ) ; }
void spi_stack_slave_message_loop_return(char *data, uint16_t length) { if(spi_stack_buffer_size_recv == 0) { SPI_EnableIt(SPI, SPI_IER_RDRF); } const uint8_t stack_id = get_stack_id_from_data(data); if(stack_id == com_stack_id || stack_id == 0) { const ComMessage *com_message = get_com_from_data(data); if(com_message->reply_func != NULL) { com_message->reply_func(COM_SPI_STACK, (void*)data); return; } } for(uint8_t i = 0; i < BRICKLET_NUM; i++) { if(bs[i].stack_id == stack_id) { baddr[i].entry(BRICKLET_TYPE_INVOCATION, COM_SPI_STACK, (void*)data); return; } } }
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); }
void spi_stack_master_init(void) { // Set starting sequence number to something that slave does not expect // (default for slave is 0) //spi_stack_master_seq = 1; for(uint8_t i = 0; i < SPI_ADDRESS_MAX; i++) { slave_status[i] = SLAVE_STATUS_ABSENT; } Pin spi_master_pins[] = {PINS_SPI}; PIO_Configure(spi_master_pins, PIO_LISTSIZE(spi_master_pins)); #ifndef CONSOLE_USART_USE_UART1 if(master_get_hardware_version() > 10) { Pin spi_select_7_20 = PIN_SPI_SELECT_MASTER_7_20; memcpy(&spi_select_master[7], &spi_select_7_20, sizeof(Pin)); } else { Pin spi_select_7_10 = PIN_SPI_SELECT_MASTER_7_10; memcpy(&spi_select_master[7], &spi_select_7_10, sizeof(Pin)); } PIO_Configure(spi_select_master, 8); #else PIO_Configure(spi_select_master, 7); #endif // Configure SPI interrupts for Master NVIC_DisableIRQ(SPI_IRQn); NVIC_ClearPendingIRQ(SPI_IRQn); NVIC_SetPriority(SPI_IRQn, PRIORITY_STACK_MASTER_SPI); NVIC_EnableIRQ(SPI_IRQn); // SPI reset SPI->SPI_CR = SPI_CR_SWRST; // Master mode configuration SPI_Configure(SPI, ID_SPI, // Master mode SPI_MR_MSTR | // Mode fault detection disabled SPI_MR_MODFDIS | // Wait until receive register empty before read SPI_MR_WDRBT | // Chip select number SPI_PCS(0) | // Delay between chip selects SPI_DLYBCS(SPI_DELAY_BETWEEN_CHIP_SELECT, BOARD_MCK)); // Configure slave select SPI_ConfigureNPCS(SPI, // slave select num 0, // Delay between consecutive transfers SPI_DLYBCT(SPI_DELAY_BETWEEN_TRANSFER, BOARD_MCK) | // Delay before first SPCK SPI_DLYBS(SPI_DELAY_BEFORE_FIRST_SPI_CLOCK, BOARD_MCK) | // SPI baud rate SPI_SCBR(SPI_CLOCK, BOARD_MCK)); // Disable RX and TX DMA transfer requests spi_stack_master_disable_dma(); // Enable SPI peripheral. SPI_Enable(SPI); spi_stack_master_reset_recv_dma_buffer(); spi_stack_master_reset_send_dma_buffer(); // Call interrupt on end of slave select SPI_EnableIt(SPI, SPI_IER_ENDRX | SPI_IER_ENDTX); }
void SPI_IrqHandler(void) { if(spi_stack_buffer_size_recv != 0) { return; } // Disable SPI interrupt and interrupt controller SPI_DisableIt(SPI, SPI_IER_RDRF); __disable_irq(); uint8_t slave_checksum = 0; uint8_t master_checksum = 0; PEARSON(slave_checksum, spi_stack_buffer_size_send); volatile uint8_t dummy; // Empty read register while((SPI->SPI_SR & SPI_SR_RDRF) == 0); dummy = SPI->SPI_RDR; while((SPI->SPI_SR & SPI_SR_RDRF) == 0); dummy = SPI->SPI_RDR; // Synchronize with master while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = 0xFF; while((SPI->SPI_SR & SPI_SR_RDRF) == 0); dummy = SPI->SPI_RDR; // Write length while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = spi_stack_buffer_size_send; // Write first byte while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = spi_stack_buffer_send[0]; PEARSON(slave_checksum, spi_stack_buffer_send[0]); // Read length from master while((SPI->SPI_SR & SPI_SR_RDRF) == 0); uint8_t master_length = SPI->SPI_RDR; PEARSON(master_checksum, master_length); // If master and slave length are 0, stop communication if(master_length == 0 && spi_stack_buffer_size_send == 0) { // Read dummy while((SPI->SPI_SR & SPI_SR_RDRF) == 0); dummy = SPI->SPI_RDR; // Write 0 (so there is no random 0xFF) SPI->SPI_TDR = 0; SPI_EnableIt(SPI, SPI_IER_RDRF); __enable_irq(); return; } // Length to transceive is maximum of slave and master length uint8_t max_length = MIN(MAX(spi_stack_buffer_size_send, master_length), SPI_STACK_BUFFER_SIZE); // Exchange data for(uint8_t i = 1; i < max_length; i++) { // Write while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = spi_stack_buffer_send[i]; PEARSON(slave_checksum, spi_stack_buffer_send[i]); // Read while((SPI->SPI_SR & SPI_SR_RDRF) == 0); spi_stack_buffer_recv[i-1] = SPI->SPI_RDR; PEARSON(master_checksum, spi_stack_buffer_recv[i-1]); } // Write CRC while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = slave_checksum; // Read last data byte while((SPI->SPI_SR & SPI_SR_RDRF) == 0); spi_stack_buffer_recv[max_length-1] = SPI->SPI_RDR; PEARSON(master_checksum, spi_stack_buffer_recv[max_length-1]); // Read CRC while((SPI->SPI_SR & SPI_SR_RDRF) == 0); uint8_t crc = SPI->SPI_RDR; // CRC correct? uint8_t slave_ack = crc == master_checksum; // Write ACK/NACK while((SPI->SPI_SR & SPI_SR_TDRE) == 0); SPI->SPI_TDR = slave_ack; // Read ACK/NACK while((SPI->SPI_SR & SPI_SR_RDRF) == 0); uint8_t master_ack = SPI->SPI_RDR; // If everything OK, set sizes accordingly if(master_ack == 1 && slave_ack == 1) { spi_stack_buffer_size_recv = master_length; spi_stack_buffer_size_send = 0; } // Last byte written is 1 or 0 (ack/nack), so there can't be an // accidental 0xFF // Enable SPI interrupt only if no new data is received. // Otherwise the spi_recv function will enable interrupt again. if(spi_stack_buffer_size_recv == 0) { SPI_EnableIt(SPI, SPI_IER_RDRF); } __enable_irq(); }
/** * \brief Application entry point. * * Configures USART1 in spi master/slave mode and SPI in slave/master mode,start * a transmission between two peripherals. * \return Unused. */ extern int main( void ) { char c ; char data = 0x0 ; /* Disable watchdog */ WDT_Disable( WDT ) ; /* Configure pins */ PIO_Configure( pins, PIO_LISTSIZE( pins ) ) ; /* Example information log */ printf( "-- USART SPI Mode Example %s --\n\r", SOFTPACK_VERSION ) ; printf( "-- %s\n\r", BOARD_NAME ) ; printf( "-- Compiled: %s %s --\n\r", __DATE__, __TIME__ ) ; /* display main menu*/ _DisplayMainmenu() ; /* configure USART1 in Master and SPI in slave mode*/ _ConfigureUsart( STATE_UM_SS ) ; _ConfigureSpi( STATE_UM_SS ) ; printf( "-- USART1 as MASTER,SPI as SLAVE.--\n\r" ) ; while ( 1 ) { c = UART_GetChar() ; switch ( c ) { case 'w': case 'W': if ( glob_state == STATE_UM_SS ) { data = SPI->SPI_RDR; printf( "0x%x\n\r", data ) ; /* slave in */ SPI_ReadBuffer( SPI, pRecvBufferSPI, BUFFER_SIZE ) ; SPI_EnableIt( SPI, SPI_IER_RXBUFF ) ; /* master out*/ USART_WriteBuffer( BOARD_USART_BASE, Buffer, BUFFER_SIZE ) ; while ( !recvDone ) ; if ( recvDone ) { printf( "----USART1 MASTER WRITE----\n\r" ) ; if ( strncmp( pRecvBufferSPI, Buffer, BUFFER_SIZE ) ) { printf( " -F-: Failed!\n\r" ) ; } else { /* successfully received*/ _DumpInfo( pRecvBufferSPI, BUFFER_SIZE ) ; } printf( "----END of USART1 MASTER WRITE----\n\r" ) ; memset( pRecvBufferSPI, 0, sizeof( pRecvBufferSPI ) ) ; recvDone = false ; } } else { data = USART1->US_RHR ; printf( "US_RHR:0x%x\n\r", data ) ; /* slave in */ USART_ReadBuffer( USART1, pRecvBufferUSART1, BUFFER_SIZE ) ; USART_EnableIt( USART1, US_IER_RXBUFF ) ; printf( "----SPI MASTER WRITE----\n\r" ) ; /* master out*/ SPI_WriteBuffer( SPI, Buffer, BUFFER_SIZE ) ; while ( !recvDone ) ; if ( recvDone ) { if ( strncmp( pRecvBufferUSART1, Buffer, BUFFER_SIZE ) ) { printf( " -F-: Failed!\n\r" ) ; } else { /* successfully received*/ _DumpInfo( pRecvBufferUSART1, BUFFER_SIZE ) ; } printf( "----END of SPI MASTER WRITE----\n\r" ) ; memset( pRecvBufferUSART1, 0, sizeof( pRecvBufferUSART1 ) ) ; recvDone = false ; } } break ; case 'r': case 'R': if ( glob_state == STATE_UM_SS ) { data = USART1->US_RHR ; printf( "US_RHR:0x%x\n\r", data ) ; /* slave out */ SPI_WriteBuffer( SPI, Buffer, BUFFER_SIZE ) ; /* master read */ USART_ReadBuffer( USART1, pRecvBufferUSART1, BUFFER_SIZE ) ; USART_EnableIt( USART1, US_IER_RXBUFF ) ; /* start transmission */ USART_WriteBuffer( BOARD_USART_BASE, Buffer1, BUFFER_SIZE ) ; printf( "----USART1 MASTER READ----\n\r" ) ; while ( !recvDone ) ; if ( recvDone ) { if ( strncmp( pRecvBufferUSART1, Buffer, BUFFER_SIZE ) ) { printf( " -F-: Failed!\n\r" ) ; } else { /* successfully received*/ _DumpInfo( pRecvBufferUSART1, BUFFER_SIZE ) ; } printf( "----END of USART1 MASTER READ----\n\r" ) ; memset( pRecvBufferUSART1, 0, sizeof( pRecvBufferUSART1 ) ) ; recvDone = false ; } } else { data = SPI->SPI_RDR ; printf( "SPI_RDR:0x%x\n\r", data ) ; /* slave out */ USART_WriteBuffer( USART1, Buffer, BUFFER_SIZE ) ; printf( "----SPI MASTER READ----\n\r" ) ; /* master read */ SPI_ReadBuffer( SPI, pRecvBufferSPI, BUFFER_SIZE ) ; SPI_EnableIt( SPI, SPI_IER_RXBUFF ) ; /* start transmission */ SPI_WriteBuffer( SPI, Buffer1, BUFFER_SIZE ) ; while ( !recvDone ) ; if ( recvDone ) { if ( strncmp( pRecvBufferSPI, Buffer, BUFFER_SIZE ) ) { printf( " -F-: Failed!\n\r" ) ; } else { /* successfully received */ _DumpInfo( pRecvBufferSPI, BUFFER_SIZE ) ; } printf("----END of SPI MASTER READ----\n\r"); memset(pRecvBufferSPI,0,sizeof(pRecvBufferSPI)); recvDone = false; } } break ; case 's': case 'S': if ( glob_state == STATE_UM_SS ) { glob_state = STATE_US_SM ; _ConfigureUsart( glob_state ) ; _ConfigureSpi( glob_state ) ; printf( "-- USART1 as SLAVE,SPI as MASTER\n\r" ) ; } else { glob_state = STATE_UM_SS ; _ConfigureUsart( glob_state ) ; _ConfigureSpi( glob_state ) ; printf( "-- USART1 as MASTER,SPI as SLAVE\n\r" ) ; } break ; case 'm': case 'M': _DisplayMainmenu() ; break ; } } }
/** * \brief usart_spi Application entry point. * * \return Unused (ANSI-C compatibility). */ extern int main(void) { uint8_t ucKey, i; /* Disable watchdog */ WDT_Disable(WDT); SCB_EnableICache(); SCB_EnableDCache(); /* Configure systick for 1 ms. */ TimeTick_Configure(); /* Output example information */ printf("-- USART SPI Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); /* Display menu */ _DisplayMainmenu(); while (1) { ucKey = DBG_GetChar(); switch (ucKey) { /*usart as spi master*/ case 'm': case 'M': /* Configure pins*/ PIO_Configure(pins1, PIO_LISTSIZE(pins1)); /* Configure USART as SPI master */ _ConfigureUsartAsSpiMaster(); /* Configure SPi slave */ _ConfigureSpiSlave(); printf("-I- Configure USART as spi master ...\n\r"); SPI_EnableIt(SPI, SPI_IER_RDRF); SPI_Enable(SPI); USART_EnableIt(USART, UART_IER_RXRDY); for (i = 0; (pTxBuffer1[i]!='\0' && pTxBuffer2[i]!='\0'); i++) { while ((SPI->SPI_SR & SPI_SR_TXEMPTY) == 0); SPI->SPI_TDR = ((uint16_t)pTxBuffer2[i]) | SPI_PCS( 0 ); USART_Write( USART, pTxBuffer1[i], 0); } break; /*usart as spi slave*/ case 's': case 'S': printf("-I- Configure USART as spi slave...\n\r"); /* Configure pins*/ PIO_Configure(pins2, PIO_LISTSIZE(pins2)); /* Configure USART as SPI slave */ _ConfigureUsartAsSpiSlave(); /* Configure SPI master */ _ConfigureSpiMaster(); USART_EnableIt(USART, UART_IER_RXRDY); SPI_EnableIt(SPI, SPI_IER_RDRF); SPI_Enable(SPI); for (i = 0; (pTxBuffer1[i]!='\0' && pTxBuffer2[i]!='\0'); i++) { USART_Write(USART, (uint16_t)pTxBuffer2[i], 0); SPI_Write( SPI, 1, (uint16_t)pTxBuffer1[i]); } break; case 'h': case 'H': _DisplayMainmenu(); break; } } }