📄 spi_isr.c
字号:
//*---------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*---------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*-----------------------------------------------------------------------------
//* File Name : serial_periph_1.c
//* Object : Serial Peripheral Driver Library.
//*
//* 1.0 04/01/00 JCZ : Creation
//* 1.1 12/03/01 HI : Multi Chip select correction
//*---------------------------------------------------------------------------
#include "appli\includes\spi1.h"
#include "services\obj_romboot.h"
//*-----------------------------------------------------------------------------
//* Function Name : serial_periph_1_handler
//* Object : SPI Fixed Peripheral C interrupt handler.
//* Input Parameters : <serial_periph_1_desc> = SPI Fixed Descriptor
//* Output Parameters : none
//* Functions called : none
//*-----------------------------------------------------------------------------
void spi1_c_handler( AT91PS_DataflashDesc pSpi1Desc )
//* Begin
{
AT91PS_SPI spi_pt = pSpi1Desc->spi_desc->spi_base ;
AT91PS_SpiDataDesc spi_data = pSpi1Desc->SpiData ;
u_int status ;
while (( status = ( spi_pt->SP_SR & spi_pt->SP_IMR )) != 0 )
{
//* If End of Transmit Transfer interrupt occurred
if (( status & SP_ENDTX) != 0 )
{
//* Clear the End Transmit Bit in the status
status &= ~SP_ENDTX ;
//* Switch SPI Driver Status
switch ( spi_data->state )
{
case SERIAL_PERIPH_1_TX_CMD_ONLY :
//* Disable the Transmit Interrupt
spi_pt->SP_IDR = SP_ENDTX ;
//* Next State
spi_data->state = SERIAL_PERIPH_1_RX_CMD_ONLY ;
break ;
case SERIAL_PERIPH_1_TX_CMD :
//* Next State
spi_data->state = SERIAL_PERIPH_1_RX_CMD ;
//* Initialize the next Transmit Pointer
spi_pt->SP_TPR = (u_int) spi_data->tx_data_pt ;
//* Intialize the next Transmit Counters
spi_pt->SP_TCR = spi_data->tx_data_size ;
break ;
case SERIAL_PERIPH_1_TX_DATA :
//* Next State
spi_data->state = SERIAL_PERIPH_1_RX_DATA ;
//* Disable the Transmit Interrupt
spi_pt->SP_IDR = SP_ENDTX ;
break ;
default :
spi_data->state = SERIAL_PERIPH_1_IDLE ;
spi_pt->SP_IDR = (SP_ENDRX | SP_ENDTX);
}
//* EndSwitch
}
//* EndIf
//* If End of Receive Transfer interrupt occurred
if (( status & SP_ENDRX) != 0 )
{
//* Clear the End Receive Bit in the status
status &= ~SP_ENDRX ;
//* Switch state of the SPI Driver
switch ( spi_data->state )
{
case SERIAL_PERIPH_1_RX_CMD_ONLY :
//* Disable the Transmit Interrupt
spi_pt->SP_IDR = SP_ENDRX ;
//* Next State
spi_data->state = SERIAL_PERIPH_1_IDLE ;
break ;
case SERIAL_PERIPH_1_RX_CMD :
//* Next State
spi_data->state = SERIAL_PERIPH_1_TX_DATA ;
//* Initialize the next Receive Pointer
spi_pt->SP_RPR = (u_int) spi_data->rx_data_pt ;
//* Initialize the next Receive Counter
spi_pt->SP_RCR = spi_data->rx_data_size ;
break ;
case SERIAL_PERIPH_1_RX_DATA :
//* Receive completed
spi_data->state = SERIAL_PERIPH_1_IDLE ;
//* Disable the Transmit Interrupt
spi_pt->SP_IDR = SP_ENDRX ;
break ;
default :
spi_data->state = SERIAL_PERIPH_1_IDLE ;
spi_pt->SP_IDR = (SP_ENDRX | SP_ENDTX);
}
//* EndSwitch
}
//* EndIf
if (( status & SP_OVRES) != 0 )
{
spi_data->state = SERIAL_PERIPH_1_IDLE ;
spi_pt->SP_IDR = SP_OVRES ;
}
}
//* EndWhile
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : spi1_open
//* Object :
//* Input Parameters : Peripheral Description address
//* Output Parameters :
//* Functions called :
//*-----------------------------------------------------------------------------
void spi1_open ( AT91PS_DataflashDesc pSpi1Desc)
//* Begin
{
u_int mode_spi = SPI_MASTER ;
AT91PS_SPI spi_pt = pSpi1Desc->spi_desc->spi_base ;
if ((pSpi1Desc->mode_spi & SP_PCSDEC) == SP_PCSDEC)
mode_spi |= (SPI_NPCS0_USED | SPI_NPCS1_USED | SPI_NPCS2_USED | SPI_NPCS3_USED);
else
{
switch ( pSpi1Desc->spi_periph_id )
{
case 0: mode_spi |= SPI_NPCS0_USED ; break ;
case 1: mode_spi |= SPI_NPCS1_USED ; break ;
case 2: mode_spi |= SPI_NPCS2_USED ; break ;
case 3: mode_spi |= SPI_NPCS3_USED ; break ;
default : break;
}
}
//* Open the SPI peripheral
at91_spi_open ( APMC_BASE, pSpi1Desc->spi_desc, mode_spi ) ;
//* Initialize the SPI Interrupt
at91_irq_open ( AIC_BASE, pSpi1Desc->spi_desc->periph_id ,
3, AIC_SRCTYPE_INT_LEVEL_SENSITIVE ,
pSpi1Desc->asm_handler ) ;
//* Initialize SPI Mode register
mode_spi = pSpi1Desc->mode_spi | SP_MSTR ;
if ((pSpi1Desc->mode_spi & SP_PCSDEC) == SP_PCSDEC)
mode_spi |= (pSpi1Desc->spi_periph_id << 16) ;
else
{
if (pSpi1Desc->spi_periph_id < 4)
{
switch ( pSpi1Desc->spi_periph_id )
{
case 0 : mode_spi |= SP_PCS0 ; break ;
case 1 : mode_spi |= SP_PCS1 ; break ;
case 2 : mode_spi |= SP_PCS2 ; break ;
case 3 : mode_spi |= SP_PCS3 ; break ;
default : break;
}
}
}
spi_pt->SP_MR = mode_spi ;
if ( pSpi1Desc->spi_periph_id < 4 )
{
//* Program the corresponding Chip Select Register
spi_pt->SP_CSR[pSpi1Desc->spi_periph_id] = pSpi1Desc->mode_spi_periph ;
}
else
{
//* Program the corresponding Chip Select Register
spi_pt->SP_CSR[pSpi1Desc->spi_periph_id >> 2] = pSpi1Desc->mode_spi_periph ;
}
//* Enable the PDC transfert
spi_pt->SP_PTCR = SP_TXTEN + SP_RXTEN;
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : serial_periph_1_close
//* Object :
//* Input Parameters :
//* Output Parameters :
//* Functions called :
//*-----------------------------------------------------------------------------
void spi1_close ( AT91PS_DataflashDesc pSpi1Desc )
//* Begin
{
AT91PS_SPI spi_pt = pSpi1Desc->spi_desc->spi_base ;
//* Enable the PDC transfert
spi_pt->SP_PTCR = (SP_TXTDIS + SP_RXTDIS);
//* Close the SPI peripheral
at91_spi_close ( APMC_BASE, pSpi1Desc->spi_desc ) ;
//* Close the SPI interrupt
at91_irq_close ( AIC_BASE, pSpi1Desc->spi_desc->periph_id ) ;
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : serial_periph_1_write
//* Object :
//* Input Parameters :
//* Output Parameters :
//* Functions called :
//*-----------------------------------------------------------------------------
void spi1_write ( AT91PS_DataflashDesc pSpi1Desc )
//* Begin
{
AT91PS_SPI spi_pt = pSpi1Desc->spi_desc->spi_base ;
AT91PS_SpiDataDesc spi_data = pSpi1Desc->SpiData ;
if ( spi_data->tx_data_size == 0 )
spi_data->state = SERIAL_PERIPH_1_TX_CMD_ONLY ;
else
spi_data->state = SERIAL_PERIPH_1_TX_CMD ;
//* Initialize the Transmit and Receive Pointer
spi_pt->SP_RPR = (u_int)spi_data->rx_cmd_pt ;
spi_pt->SP_TPR = (u_int)spi_data->tx_cmd_pt ;
//* Intialize the Transmit and Receive Counters
spi_pt->SP_RCR = spi_data->rx_cmd_size ;
spi_pt->SP_TCR = spi_data->tx_cmd_size ;
//* Enable TDRE and RDRF Interrupt
spi_pt->SP_IER = SP_ENDRX|SP_ENDTX ;
}
//* End
//*-----------------------------------------------------------------------------
//* Function Name : get_spi_status
//* Object :
//* Input Parameters :
//* Output Parameters :
//* Functions called :
//*-----------------------------------------------------------------------------
u_int spi1_getStatus ( AT91PS_DataflashDesc pSpi1Desc )
//* Begin
{
return ( pSpi1Desc->SpiData->state ) ;
}
//* End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -