Example #1
0
/**
 * \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();
        }
    }

}
Example #2
0
File: main.c Project: gstroe/Arm
/**
 * \brief Configures spi in slave mode.
 */
static void _ConfigureSpiSlave( void )
{
	/* Configure SPI slave mode */
	SPI_Configure(SPI, ID_SPI, SPI_PCS(0));

	NVIC_ClearPendingIRQ(SPI_IRQn);
	NVIC_SetPriority(SPI_IRQn ,1);
	NVIC_EnableIRQ(SPI_IRQn);
	SPI_DisableIt(SPI, 0xffffffff);

	SPI_ConfigureNPCS(SPI, 0, 0);
}
Example #3
0
File: main.c Project: gstroe/Arm
/**
 * \brief Configures spi in master mode.
 */
static void _ConfigureSpiMaster(void)
{
	/* Configure SPI master mode */
	SPI_Configure(SPI, ID_SPI, (SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(1)));

	NVIC_ClearPendingIRQ(SPI_IRQn);
	NVIC_SetPriority(SPI_IRQn ,1);
	NVIC_EnableIRQ(SPI_IRQn);
	SPI_DisableIt(SPI, 0xffffffff);

	SPI_ConfigureNPCS(SPI, 1,
					  SPI_DLYBCT( 100, BOARD_MCK ) |
					  SPI_DLYBS(100, BOARD_MCK) |
					  SPI_SCBR( spiClock, BOARD_MCK) |
					  SPI_CSR_BITS_8_BIT);
}
void spi_stack_master_disable_dma(void) {
	SPI_DisableIt(SPI, SPI_IER_ENDRX | SPI_IER_ENDTX);
	SPI->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS;
	spi_stack_deselect();
}
Example #5
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();
}