Ejemplo n.º 1
0
Archivo: spid.c Proyecto: gstroe/Arm
//------------------------------------------------------------------------------
/// The SPI_Handler must be called by the SPI Interrupt Service Routine with the
/// corresponding Spi instance.
/// The SPI_Handler will unlock the Spi semaphore and invoke the upper application
/// callback.
/// \param pSpid  Pointer to a Spid instance.
//------------------------------------------------------------------------------
void SPID_Handler(Spid *pSpid)
{
	SpidCmd *pSpidCmd = pSpid->pCurrentCommand;
	AT91S_SPI *pSpiHw = pSpid->pSpiHw;
	volatile unsigned int spiSr;

	// Read the status register
	spiSr = READ_SPI(pSpiHw, SPI_SR);

	if (spiSr & AT91C_SPI_RXBUFF) {
		// Disable transmitter and receiver
		WRITE_SPI(pSpiHw, SPI_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS);

		// Disable the SPI clock
		WRITE_PMC(AT91C_BASE_PMC, PMC_PCDR, (1 << pSpid->spiId));

		// Disable buffer complete interrupt
		WRITE_SPI(pSpiHw, SPI_IDR, AT91C_SPI_RXBUFF);

		// Release the dataflash semaphore
		pSpid->semaphore++;

		// Invoke the callback associated with the current command
		if (pSpidCmd && pSpidCmd->callback)

			pSpidCmd->callback(0, pSpidCmd->pArgument);

		// Nothing must be done after. A new DF operation may have been started
		// in the callback function.
	}
}
Ejemplo n.º 2
0
/**
 * \brief SPI xDMA Rx callback
 * Invoked on SPi DMA reception done.
 * \param channel DMA channel.
 * \param pArg Pointer to callback argument - Pointer to Spid instance.   
 */ 
static void SPID_Rx_Cb(uint32_t channel, Spid* pArg)
{
    SpidCmd *pSpidCmd = pArg->pCurrentCommand;
    Spi *pSpiHw = pArg->pSpiHw;
    if (channel != spiDmaRxChannel)
        return;
    
    /* Disable the SPI TX & RX */
    SPI_Disable ( pSpiHw );
 
    /* Configure and enable interrupt on RC compare */    
    NVIC_ClearPendingIRQ(XDMAC_IRQn);
    NVIC_DisableIRQ(XDMAC_IRQn);
    
    /* Disable the SPI Peripheral */
    PMC_DisablePeripheral ( pArg->spiId );
    
    /* Release CS */
    SPI_ReleaseCS(pSpiHw);
    
    /* Release the DMA channels */
    XDMAD_FreeChannel(pArg->pXdmad, spiDmaRxChannel);
    XDMAD_FreeChannel(pArg->pXdmad, spiDmaTxChannel);

    /* Release the dataflash semaphore */
    pArg->semaphore++;
        
    printf("\n\r%s\n\r",pArg->pCurrentCommand->pRxBuff);
    
    /* Invoke the callback associated with the current command */
    if (pSpidCmd && pSpidCmd->callback) {
        //printf("p %d", pArg->semaphore);
        pSpidCmd->callback(0, pSpidCmd->pArgument);
    }
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------------
/// SPI DMA transfer ISR, Handle RX complete
//------------------------------------------------------------------------------
void SPID_Handler(Spid *pSpid)
{
    unsigned int dmaStatus;
    SpidCmd *pSpidCmd = pSpid->pCurrentCommand;
    AT91S_SPI *pSpiHw = pSpid->pSpiHw;

    dmaStatus = DMA_GetStatus();

    if ((dmaStatus & AT91C_CBTC) == 0)
        return;

    if ((dmaStatus & (DMA_CBTC << DMA_CHANNEL_0)) == 0)
        return;

    // Disable the SPI TX & RX
    WRITE_SPI(pSpiHw, SPI_CR, AT91C_SPI_SPIDIS);
    // Disable the SPI Peripheral
    PERIPH_DISABLE(pSpid->spiId);

    // Disable DMA
    DMA_Disable();
    // Disable DMA Peripheral
    PERIPH_DISABLE(AT91C_ID_HDMA);
    
    // Release the dataflash semaphore
    pSpid->semaphore++;
        
    // Invoke the callback associated with the current command
    if (pSpidCmd && pSpidCmd->callback) {
    
        pSpidCmd->callback(0, pSpidCmd->pArgument);
    }
        
}