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;
}
Beispiel #2
0
/**
 * \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 ) ;
}
Beispiel #3
0
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;
		}
	}
}
Beispiel #4
0
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);
}
Beispiel #6
0
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();
}
Beispiel #7
0
/**
 * \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 ;

        }

    }
}
Beispiel #8
0
Datei: main.c Projekt: gstroe/Arm
/**
 *  \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;
		}
	}
}