444 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			444 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/**********************************************************************
							 | 
						||
| 
								 | 
							
								* $Id$      lpc17xx_spi.c               2010-05-21
							 | 
						||
| 
								 | 
							
								*//**
							 | 
						||
| 
								 | 
							
								* @file     lpc17xx_spi.c
							 | 
						||
| 
								 | 
							
								* @brief    Contains all functions support for SPI firmware library on LPC17xx
							 | 
						||
| 
								 | 
							
								* @version  2.0
							 | 
						||
| 
								 | 
							
								* @date     21. May. 2010
							 | 
						||
| 
								 | 
							
								* @author   NXP MCU SW Application Team
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								* Copyright(C) 2010, NXP Semiconductor
							 | 
						||
| 
								 | 
							
								* All rights reserved.
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								***********************************************************************
							 | 
						||
| 
								 | 
							
								* Software that is described herein is for illustrative purposes only
							 | 
						||
| 
								 | 
							
								* which provides customers with programming information regarding the
							 | 
						||
| 
								 | 
							
								* products. This software is supplied "AS IS" without any warranties.
							 | 
						||
| 
								 | 
							
								* NXP Semiconductors assumes no responsibility or liability for the
							 | 
						||
| 
								 | 
							
								* use of the software, conveys no license or title under any patent,
							 | 
						||
| 
								 | 
							
								* copyright, or mask work right to the product. NXP Semiconductors
							 | 
						||
| 
								 | 
							
								* reserves the right to make changes in the software without
							 | 
						||
| 
								 | 
							
								* notification. NXP Semiconductors also make no representation or
							 | 
						||
| 
								 | 
							
								* warranty that such application will be suitable for the specified
							 | 
						||
| 
								 | 
							
								* use without further testing or modification.
							 | 
						||
| 
								 | 
							
								* Permission to use, copy, modify, and distribute this software and its
							 | 
						||
| 
								 | 
							
								* documentation is hereby granted, under NXP Semiconductors'
							 | 
						||
| 
								 | 
							
								* relevant copyright in the software, without fee, provided that it
							 | 
						||
| 
								 | 
							
								* is used in conjunction with NXP Semiconductors microcontrollers.  This
							 | 
						||
| 
								 | 
							
								* copyright, permission, and disclaimer notice must appear in all copies of
							 | 
						||
| 
								 | 
							
								* this code.
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Peripheral group ----------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								/** @addtogroup SPI
							 | 
						||
| 
								 | 
							
								 * @{
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Includes ------------------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								#include "lpc17xx_spi.h"
							 | 
						||
| 
								 | 
							
								#include "lpc17xx_clkpwr.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* If this source file built with example, the LPC17xx FW library configuration
							 | 
						||
| 
								 | 
							
								 * file in each example directory ("lpc17xx_libcfg.h") must be included,
							 | 
						||
| 
								 | 
							
								 * otherwise the default FW library configuration file must be included instead
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#ifdef __BUILD_WITH_EXAMPLE__
							 | 
						||
| 
								 | 
							
								#include "lpc17xx_libcfg.h"
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#include "lpc17xx_libcfg_default.h"
							 | 
						||
| 
								 | 
							
								#endif /* __BUILD_WITH_EXAMPLE__ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _SPI
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Public Functions ----------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								/** @addtogroup SPI_Public_Functions
							 | 
						||
| 
								 | 
							
								 * @{
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Setup clock rate for SPI device
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral definition, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @param[in]   target_clock : clock of SPI (Hz)
							 | 
						||
| 
								 | 
							
								 * @return      None
							 | 
						||
| 
								 | 
							
								 ***********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t spi_pclk;
							 | 
						||
| 
								 | 
							
								    uint32_t prescale, temp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (SPIx == LPC_SPI){
							 | 
						||
| 
								 | 
							
								        spi_pclk =  CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SPI);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    prescale = 8;
							 | 
						||
| 
								 | 
							
								    // Find closest clock to target clock
							 | 
						||
| 
								 | 
							
								    while (1){
							 | 
						||
| 
								 | 
							
								        temp = target_clock * prescale;
							 | 
						||
| 
								 | 
							
								        if (temp >= spi_pclk){
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        prescale += 2;
							 | 
						||
| 
								 | 
							
								        if(prescale >= 254){
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Write to register
							 | 
						||
| 
								 | 
							
								    SPIx->SPCCR = SPI_SPCCR_COUNTER(prescale);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       De-initializes the SPIx peripheral registers to their
							 | 
						||
| 
								 | 
							
								*                  default reset values.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      None
							 | 
						||
| 
								 | 
							
								 **********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_DeInit(LPC_SPI_TypeDef *SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (SPIx == LPC_SPI){
							 | 
						||
| 
								 | 
							
								        /* Set up clock and power for SPI module */
							 | 
						||
| 
								 | 
							
								        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, DISABLE);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Get data bit size per transfer
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      number of bit per transfer, could be 8-16
							 | 
						||
| 
								 | 
							
								 **********************************************************************/
							 | 
						||
| 
								 | 
							
								uint8_t SPI_GetDataSize (LPC_SPI_TypeDef *SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								    return ((SPIx->SPCR)>>8 & 0xF);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Initializes the SPIx peripheral according to the specified
							 | 
						||
| 
								 | 
							
								*               parameters in the UART_ConfigStruct.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPI_ConfigStruct Pointer to a SPI_CFG_Type structure
							 | 
						||
| 
								 | 
							
								*                    that contains the configuration information for the
							 | 
						||
| 
								 | 
							
								*                    specified SPI peripheral.
							 | 
						||
| 
								 | 
							
								 * @return      None
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(SPIx == LPC_SPI){
							 | 
						||
| 
								 | 
							
								        /* Set up clock and power for UART module */
							 | 
						||
| 
								 | 
							
								        CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, ENABLE);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Configure SPI, interrupt is disable as default
							 | 
						||
| 
								 | 
							
								    tmp = ((SPI_ConfigStruct->CPHA) | (SPI_ConfigStruct->CPOL) \
							 | 
						||
| 
								 | 
							
								        | (SPI_ConfigStruct->DataOrder) | (SPI_ConfigStruct->Databit) \
							 | 
						||
| 
								 | 
							
								        | (SPI_ConfigStruct->Mode) | SPI_SPCR_BIT_EN) & SPI_SPCR_BITMASK;
							 | 
						||
| 
								 | 
							
								    // write back to SPI control register
							 | 
						||
| 
								 | 
							
								    SPIx->SPCR = tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Set clock rate for SPI peripheral
							 | 
						||
| 
								 | 
							
								    SPI_SetClock(SPIx, SPI_ConfigStruct->ClockRate);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If interrupt flag is set, Write '1' to Clear interrupt flag
							 | 
						||
| 
								 | 
							
								    if (SPIx->SPINT & SPI_SPINT_INTFLAG){
							 | 
						||
| 
								 | 
							
								        SPIx->SPINT = SPI_SPINT_INTFLAG;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*****************************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief        Fills each SPI_InitStruct member with its default value:
							 | 
						||
| 
								 | 
							
								*               - CPHA = SPI_CPHA_FIRST
							 | 
						||
| 
								 | 
							
								*               - CPOL = SPI_CPOL_HI
							 | 
						||
| 
								 | 
							
								*               - ClockRate = 1000000
							 | 
						||
| 
								 | 
							
								*               - DataOrder = SPI_DATA_MSB_FIRST
							 | 
						||
| 
								 | 
							
								*               - Databit = SPI_DATABIT_8
							 | 
						||
| 
								 | 
							
								*               - Mode = SPI_MASTER_MODE
							 | 
						||
| 
								 | 
							
								* @param[in]    SPI_InitStruct Pointer to a SPI_CFG_Type structure
							 | 
						||
| 
								 | 
							
								*                    which will be initialized.
							 | 
						||
| 
								 | 
							
								* @return       None
							 | 
						||
| 
								 | 
							
								*******************************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->CPHA = SPI_CPHA_FIRST;
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->CPOL = SPI_CPOL_HI;
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->ClockRate = 1000000;
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->DataOrder = SPI_DATA_MSB_FIRST;
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->Databit = SPI_DATABIT_8;
							 | 
						||
| 
								 | 
							
								    SPI_InitStruct->Mode = SPI_MASTER_MODE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Transmit a single data through SPIx peripheral
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @param[in]   Data    Data to transmit (must be 16 or 8-bit long,
							 | 
						||
| 
								 | 
							
								 *                      this depend on SPI data bit number configured)
							 | 
						||
| 
								 | 
							
								 * @return      none
							 | 
						||
| 
								 | 
							
								 **********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_SendData(LPC_SPI_TypeDef* SPIx, uint16_t Data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SPIx->SPDR = Data & SPI_SPDR_BITMASK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Receive a single data from SPIx peripheral
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      Data received (16-bit long)
							 | 
						||
| 
								 | 
							
								 **********************************************************************/
							 | 
						||
| 
								 | 
							
								uint16_t SPI_ReceiveData(LPC_SPI_TypeDef* SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ((uint16_t) (SPIx->SPDR & SPI_SPDR_BITMASK));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       SPI     Read write data function
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    Pointer to SPI peripheral, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @param[in]   dataCfg Pointer to a SPI_DATA_SETUP_Type structure that
							 | 
						||
| 
								 | 
							
								 *                      contains specified information about transmit
							 | 
						||
| 
								 | 
							
								 *                      data configuration.
							 | 
						||
| 
								 | 
							
								 * @param[in]   xfType  Transfer type, should be:
							 | 
						||
| 
								 | 
							
								 *                      - SPI_TRANSFER_POLLING: Polling mode
							 | 
						||
| 
								 | 
							
								 *                      - SPI_TRANSFER_INTERRUPT: Interrupt mode
							 | 
						||
| 
								 | 
							
								 * @return      Actual Data length has been transferred in polling mode.
							 | 
						||
| 
								 | 
							
								 *              In interrupt mode, always return (0)
							 | 
						||
| 
								 | 
							
								 *              Return (-1) if error.
							 | 
						||
| 
								 | 
							
								 * Note: This function can be used in both master and slave mode.
							 | 
						||
| 
								 | 
							
								 ***********************************************************************/
							 | 
						||
| 
								 | 
							
								int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, \
							 | 
						||
| 
								 | 
							
								                        SPI_TRANSFER_Type xfType)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *rdata8;
							 | 
						||
| 
								 | 
							
								    uint8_t *wdata8;
							 | 
						||
| 
								 | 
							
								    uint16_t *rdata16;
							 | 
						||
| 
								 | 
							
								    uint16_t *wdata16;
							 | 
						||
| 
								 | 
							
								    uint32_t stat;
							 | 
						||
| 
								 | 
							
								    uint32_t temp;
							 | 
						||
| 
								 | 
							
								    uint8_t dataword;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //read for empty buffer
							 | 
						||
| 
								 | 
							
								    temp = SPIx->SPDR;
							 | 
						||
| 
								 | 
							
								    //dummy to clear status
							 | 
						||
| 
								 | 
							
								    temp = SPIx->SPSR;
							 | 
						||
| 
								 | 
							
								    dataCfg->counter = 0;
							 | 
						||
| 
								 | 
							
								    dataCfg->status = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(SPI_GetDataSize (SPIx) == 8)
							 | 
						||
| 
								 | 
							
								        dataword = 0;
							 | 
						||
| 
								 | 
							
								    else dataword = 1;
							 | 
						||
| 
								 | 
							
								    if (xfType == SPI_TRANSFER_POLLING){
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (dataword == 0){
							 | 
						||
| 
								 | 
							
								            rdata8 = (uint8_t *)dataCfg->rx_data;
							 | 
						||
| 
								 | 
							
								            wdata8 = (uint8_t *)dataCfg->tx_data;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            rdata16 = (uint16_t *)dataCfg->rx_data;
							 | 
						||
| 
								 | 
							
								            wdata16 = (uint16_t *)dataCfg->tx_data;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while(dataCfg->counter < dataCfg->length)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // Write data to buffer
							 | 
						||
| 
								 | 
							
								            if(dataCfg->tx_data == NULL){
							 | 
						||
| 
								 | 
							
								                if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, 0xFF);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, 0xFFFF);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, *wdata8);
							 | 
						||
| 
								 | 
							
								                    wdata8++;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, *wdata16);
							 | 
						||
| 
								 | 
							
								                    wdata16++;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // Wait for transfer complete
							 | 
						||
| 
								 | 
							
								            while (!((stat = SPIx->SPSR) & SPI_SPSR_SPIF));
							 | 
						||
| 
								 | 
							
								            // Check for error
							 | 
						||
| 
								 | 
							
								            if (stat & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){
							 | 
						||
| 
								 | 
							
								                // save status
							 | 
						||
| 
								 | 
							
								                dataCfg->status = stat | SPI_STAT_ERROR;
							 | 
						||
| 
								 | 
							
								                return (dataCfg->counter);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // Read data from SPI dat
							 | 
						||
| 
								 | 
							
								            temp = (uint32_t) SPI_ReceiveData(SPIx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Store data to destination
							 | 
						||
| 
								 | 
							
								            if (dataCfg->rx_data != NULL)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                    *(rdata8) = (uint8_t) temp;
							 | 
						||
| 
								 | 
							
								                    rdata8++;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    *(rdata16) = (uint16_t) temp;
							 | 
						||
| 
								 | 
							
								                    rdata16++;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // Increase counter
							 | 
						||
| 
								 | 
							
								            if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                dataCfg->counter++;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                dataCfg->counter += 2;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Return length of actual data transferred
							 | 
						||
| 
								 | 
							
								        // save status
							 | 
						||
| 
								 | 
							
								        dataCfg->status = stat | SPI_STAT_DONE;
							 | 
						||
| 
								 | 
							
								        return (dataCfg->counter);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Interrupt mode
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Check if interrupt flag is already set
							 | 
						||
| 
								 | 
							
								        if(SPIx->SPINT & SPI_SPINT_INTFLAG){
							 | 
						||
| 
								 | 
							
								            SPIx->SPINT = SPI_SPINT_INTFLAG;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (dataCfg->counter < dataCfg->length){
							 | 
						||
| 
								 | 
							
								            // Write data to buffer
							 | 
						||
| 
								 | 
							
								            if(dataCfg->tx_data == NULL){
							 | 
						||
| 
								 | 
							
								                if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, 0xFF);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, 0xFFFF);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (dataword == 0){
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, (*(uint8_t *)dataCfg->tx_data));
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    SPI_SendData(SPIx, (*(uint16_t *)dataCfg->tx_data));
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            SPI_IntCmd(SPIx, ENABLE);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            // Save status
							 | 
						||
| 
								 | 
							
								            dataCfg->status = SPI_STAT_DONE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return (0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Enable or disable SPIx interrupt.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @param[in]   NewState New state of specified UART interrupt type,
							 | 
						||
| 
								 | 
							
								 *              should be:
							 | 
						||
| 
								 | 
							
								 *              - ENALBE: Enable this SPI interrupt.
							 | 
						||
| 
								 | 
							
								*               - DISALBE: Disable this SPI interrupt.
							 | 
						||
| 
								 | 
							
								 * @return      None
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (NewState == ENABLE)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        SPIx->SPCR |= SPI_SPCR_SPIE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        SPIx->SPCR &= (~SPI_SPCR_SPIE) & SPI_SPCR_BITMASK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Checks whether the SPI interrupt flag is set or not.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      The new state of SPI Interrupt Flag (SET or RESET)
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								IntStatus SPI_GetIntStatus (LPC_SPI_TypeDef *SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ((SPIx->SPINT & SPI_SPINT_INTFLAG) ? SET : RESET);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Clear SPI interrupt flag.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      None
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								void SPI_ClearIntPending(LPC_SPI_TypeDef *SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SPIx->SPINT = SPI_SPINT_INTFLAG;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Get current value of SPI Status register in SPIx peripheral.
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIx    SPI peripheral selected, should be LPC_SPI
							 | 
						||
| 
								 | 
							
								 * @return      Current value of SPI Status register in SPI peripheral.
							 | 
						||
| 
								 | 
							
								 * Note:    The return value of this function must be used with
							 | 
						||
| 
								 | 
							
								 *          SPI_CheckStatus() to determine current flag status
							 | 
						||
| 
								 | 
							
								 *          corresponding to each SPI status type. Because some flags in
							 | 
						||
| 
								 | 
							
								 *          SPI Status register will be cleared after reading, the next reading
							 | 
						||
| 
								 | 
							
								 *          SPI Status register could not be correct. So this function used to
							 | 
						||
| 
								 | 
							
								 *          read SPI status register in one time only, then the return value
							 | 
						||
| 
								 | 
							
								 *          used to check all flags.
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								uint32_t SPI_GetStatus(LPC_SPI_TypeDef* SPIx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPIx(SPIx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (SPIx->SPSR & SPI_SPSR_BITMASK);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/********************************************************************//**
							 | 
						||
| 
								 | 
							
								 * @brief       Checks whether the specified SPI Status flag is set or not
							 | 
						||
| 
								 | 
							
								 *              via inputSPIStatus parameter.
							 | 
						||
| 
								 | 
							
								 * @param[in]   inputSPIStatus Value to check status of each flag type.
							 | 
						||
| 
								 | 
							
								 *              This value is the return value from SPI_GetStatus().
							 | 
						||
| 
								 | 
							
								 * @param[in]   SPIStatus   Specifies the SPI status flag to check,
							 | 
						||
| 
								 | 
							
								 *              should be one of the following:
							 | 
						||
| 
								 | 
							
								                - SPI_STAT_ABRT: Slave abort.
							 | 
						||
| 
								 | 
							
								                - SPI_STAT_MODF: Mode fault.
							 | 
						||
| 
								 | 
							
								                - SPI_STAT_ROVR: Read overrun.
							 | 
						||
| 
								 | 
							
								                - SPI_STAT_WCOL: Write collision.
							 | 
						||
| 
								 | 
							
								                - SPI_STAT_SPIF: SPI transfer complete.
							 | 
						||
| 
								 | 
							
								 * @return      The new state of SPIStatus (SET or RESET)
							 | 
						||
| 
								 | 
							
								 *********************************************************************/
							 | 
						||
| 
								 | 
							
								FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus,  uint8_t SPIStatus)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CHECK_PARAM(PARAM_SPI_STAT(SPIStatus));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ((inputSPIStatus & SPIStatus) ? SET : RESET);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* _SPI */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* --------------------------------- End Of File ------------------------------ */
							 |