⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 LPC2102的keil vendor code
💻 C
字号:
/*****************************************************************************
 *   spi.c:  SPI C file for NXP LPC210x Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2005.10.01  ver 1.00    Prelimnary version, first Release
*****************************************************************************/
#include "LPC210x.h"			/* LPC21XX Peripheral Registers	*/
#include "type.h"
#include "irq.h"
#include "spi.h"
#include "i2c.h"

volatile DWORD SPI0Status = 0;
volatile DWORD TxCounter = 0;

static BYTE sSPI_Initialized = 0;

/*****************************************************************************
** Function name:	SPI0_Handler
** Description:		SPI0 interrupt handler
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void SPI0_Handler (void) __irq 
{
    DWORD regValue;
  
    S0SPINT = SPI0_INT_FLAG;		/* Clear interrupt flag */
    IENABLE;						/* Handles nested interrupt */

    regValue = S0SPSR;

    if( regValue & WCOL )
    {
		SPI0Status |= SPI0_COL;
    }

    if( regValue & SPIF )
    {
		SPI0Status |= SPI0_TX_DONE;
		TxCounter++;
    }

    IDISABLE;
    VICVectAddr = 0;				/* Acknowledge Interrupt */
} // SPI0_Handler

/*****************************************************************************
** Function name:	SPI_Init
** Description:		SPI port initialization routine
** Parameter:		None
** Returned value:	true or false; if the interrupt handler	cannot be 
**					installed correctly, return false.
*****************************************************************************/
DWORD SPI_Init(void)
{
	if(sSPI_Initialized)
		return (TRUE);

    PINSEL0 &= 0xFFFF00FF;

#if SPI_LPC2106
    PINSEL0 |= 0x00005100;	// Set P0.4 as SCK0 and P0.6 as MOSI; P0.7 as SSEL0
#else
    PINSEL0 |= 0x00001100;	// Set P0.4 as SCK0 and P0.6 as MOSI
#endif

    IODIR |= SPI0_SSEL;	 	// Set P0.7 as output
    IOSET |= SPI0_SSEL;		// Set P0.7 as High

    S0SPCR = 0x00;			// Reset SPI0 control register
    S0SPCCR = 0x08;			// SPI0 rate = PCLK/S0SPCCR = 15/8 = 1.875 MHz

#if INTERRUPT_MODE			/* Interrupt mode */
	if( install_irq( SPI0_INT, (void *)SPI0Handler ) == FALSE )
    {
		return (FALSE);
    }

    S0SPCR |= SPI0_SPIE | SPI0_MSTR;	// CPOL = CPHA = 0, SPI master mode, MSB first, interrupt enabled
#else						/* Polling mode */
    S0SPCR |= SPI0_MSTR | SPI0_CPOL | SPI0_CPHA;	// Configure SPI0 as SPI master mode, CPOL:'1' - SCK is active low, CPHA:'1' - Data sampled on second clock edge of SCK
#endif

	sSPI_Initialized = 1;

    return (TRUE);
} // SPI_Init

/*****************************************************************************
** Function name:	SPI_DeInit
** Description:		SPI Port de-initialization routine
** Parameter:		None
** Returned value:	true or false; if the interrupt handler	cannot be 
**					uninstalled correctly, return false.
*****************************************************************************/
DWORD SPI_DeInit(void)
{
	if(!sSPI_Initialized)
		return (TRUE);

    PINSEL0 &= 0xFFFF00FF;

	/* Set SPI ports at non-operational state */
	IODIR &= ~(SPI0_SCK | SPI0_MOSI | SPI0_SSEL); // Set P0.4(SCK0), P0.6(MOSI0) and P0.7(SSEL0) as input ports

#if INTERRUPT_MODE			/* Interrupt mode */
	if( uninstall_irq(SPI0_INT) == FALSE )
    {
		return (FALSE);
    }
#endif

	sSPI_Initialized = 0;

    return (TRUE);
} // SPI_DeInit

/*****************************************************************************
** Function name:	SPI_Send
** Description:		This function sends a block of data to the SPI port, one
**					byte at a time.
** Parameter:		Buffer pointer; block length
** Returned value:	None
*****************************************************************************/
void SPI_Send(BYTE *buf, DWORD Length)
{
    DWORD i;

	if(sSPI_Initialized)
	{
	    if(Length == 0)
			return;

	    for(i=0; i<Length; i++)
	    {
			S0SPDR = (BYTE) *buf;

#if INTERRUPT_MODE		/* Interrupt mode */
			/* In the interrupt, there is nothing to be done if TX_DONE, SPI transfer 
			complete bit, is not set, so it's polling if the flag is set or not which 
			is being handled inside the ISR. Not an ideal example but show how the 
			interrupt is being set and handled. */ 

			while( (SPI0Status & SPI0_TX_DONE) != SPI0_TX_DONE );
				SPI0Status &= ~SPI0_TX_DONE;
#else					/* Polling mode */
			while( !(S0SPSR & SPIF) );
#endif
		
			buf++;
    	}
	}
} // SPI_Send

/*****************************************************************************
** Function name:	SPI_Receive
** Description:		This function will receive one byte of data from the SPI 
**					port. It waits until SPI transfer is completed before 
**					reading	the data register to get the SPI data.
** Parameter:		Buffer pointer
** Returned value:	None
*****************************************************************************/
void SPI_Receive(BYTE *buf)
{
	if(sSPI_Initialized)
	{
	    /* Wait for transfer complete, SPIF bit set */
#if INTERRUPT_MODE	/* Interrupt mode */
	    /* In the receive routine, there is nothing to be done if TX_DONE, or
	    SPI transfer complete bit, is not set, so it's polling if the flag is set 
	    or not which is being handled inside the ISR. Not an ideal example but 
	    show how the interrupt is being set and handled. */ 
	    while( (SPI0Status & SPI0_TX_DONE) != SPI0_TX_DONE );
	    	SPI0Status &= ~SPI0_TX_DONE;
#else				/* Polling mode */
	    while( !(S0SPSR & SPIF) );
#endif

    	*buf = S0SPDR;
	}
} // SPI_Receive

/*****************************************************************************
** Function name:	SPI_Config
** Description:		This function allows the configuration of SPI settings, which
**					includes:
** 					(1) SPI Clock Counter (S0SPCCR)
**					(2) Clock phase (CPHA)
**					(3) Clock polarity (CPOL)
**					(4) LSB First (LSBF)
**
** 					I2C data format for SPI configuration:
**
**					1. I2C0RxBuffer[1] - Second byte of I2C Rx buffer
**					 
**					- SPI Clock Counter configuration
**					- Value must be an even number that is greater than or equal to 8
**					- Size: 8 bits
**
**					2. I2C0RxBuffer[2] - Third byte of I2C Rx buffer
**
**					- bits 3~7: Not used
** 					- bit 2:    LSB First (LSBF) Control ('1': MSB first; '0': LSB first)
**					- bit 1:	Clock Polarity (CPOL) Control ('1': SCK active low; '0': SCK active high)
**					- bit 0:	Clock Phase (CPHA) Control ('1': Data sampled on first SCK clock edge; '0': Data sampled on second SCK clock edge)
**
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void SPI_Config(BYTE *buf)
{
	if(sSPI_Initialized)
	{
		/* Configuration of SPI clock counter */
		if( !(*(buf+1) % 2) && (*(buf+1) >= 8) )
		{
			S0SPCCR = *(buf+1);
		}
	
		/* Configuration of SPI Clock Phase */
		if( *(buf+2) & 1 )
			S0SPCR |= SPI0_CPHA;
		else
			S0SPCR &= ~SPI0_CPHA;
	
		/* Configuration of SPI Clock Polarity */
		if( *(buf+2) & (1<<1) )
			S0SPCR |= SPI0_CPOL;
		else
			S0SPCR &= ~SPI0_CPOL;
	
		/* Configuration of SPI LSB First direction */
		if( *(buf+2) & (1<<2) )
			S0SPCR |= SPI0_LSBF;
		else
			S0SPCR &= ~SPI0_LSBF;
	}
} // SPI_Config

/*****************************************************************************
** Function name:	SPI_OnOff
** Description:		This function allows the I2C host to enable or disable 
**					the SPI function. The I2C host is required to send an 
**					instruction	byte to enable or disable the SPI function.
**
**					SPI Enable/Disable instruction byte:
**					- 0x00: Disable SPI function
**					- 0x01: Enable SPI function
**
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void SPI_OnOff(void)
{
	if(I2C0RxBuffer[1] == 1)
		SPI_Init();
	else if(I2C0RxBuffer[1] == 0)
		SPI_DeInit();
} // SPI_OnOff

/******************************************************************************
**                            End Of File
******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -