
NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip
Diff: source/lpc17xx_ssp.c
- Revision:
- 0:1063a091a062
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/lpc17xx_ssp.c Wed Feb 17 16:22:39 2010 +0000 @@ -0,0 +1,831 @@ +/** + * @file : lpc17xx_ssp.c + * @brief : Contains all functions support for SSP firmware library on LPC17xx + * @version : 1.0 + * @date : 9. April. 2009 + * @author : HieuNguyen + ************************************************************************** + * 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. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup SSP + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_ssp.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 _SSP + +/* Private Types -------------------------------------------------------------- */ +/** @defgroup SSP_Private_Types + * @{ + */ + +/** @brief SSP device configuration structure type */ +typedef struct +{ + int32_t dataword; /* Current data word: 0 - 8 bit; 1 - 16 bit */ + uint32_t txrx_setup; /* Transmission setup */ + void (*inthandler)(LPC_SSP_TypeDef *SSPx); /* Transmission interrupt handler */ +} SSP_CFG_T; + +/** + * @} + */ + +/* Private Variables ---------------------------------------------------------- */ +/* SSP configuration data */ +static SSP_CFG_T sspdat[2]; + + +/* Private Functions ---------------------------------------------------------- */ +/** @defgroup SSP_Private_Functions + * @{ + */ + +/** + * @brief Convert from SSP peripheral to number + */ +static int32_t SSP_getNum(LPC_SSP_TypeDef *SSPx){ + if (SSPx == LPC_SSP0) { + return (0); + } else if (SSPx == LPC_SSP1) { + return (1); + } + return (-1); +} + + +/*********************************************************************//** + * @brief Standard Private SSP Interrupt handler + * @param SSPx: SSP peripheral definition, should be + * SSP0 or SSP1. + * @return None + ***********************************************************************/ +void SSP_IntHandler(LPC_SSP_TypeDef *SSPx) +{ + SSP_DATA_SETUP_Type *xf_setup; + uint16_t tmp; + int32_t sspnum; + + // Disable interrupt + SSPx->IMSC = 0; + + sspnum = SSP_getNum(SSPx); + xf_setup = (SSP_DATA_SETUP_Type *)sspdat[sspnum].txrx_setup; + + // save status + tmp = SSPx->RIS; + xf_setup->status = tmp; + + // Check overrun error + if (tmp & SSP_RIS_ROR){ + // Clear interrupt + SSPx->ICR = SSP_RIS_ROR; + // update status + xf_setup->status |= SSP_STAT_ERROR; + // Callback + if (xf_setup->callback != NULL){ + xf_setup->callback(); + } + return; + } + + if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)){ + /* check if RX FIFO contains data */ + while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (xf_setup->rx_data != NULL) + { + if (sspdat[sspnum].dataword == 0){ + *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp; + } else { + *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp; + } + } + // Increase counter + if (sspdat[sspnum].dataword == 0){ + xf_setup->rx_cnt++; + } else { + xf_setup->rx_cnt += 2; + } + } + + while ((SSPx->SR & SSP_SR_TNF) && (xf_setup->tx_cnt != xf_setup->length)){ + // Write data to buffer + if(xf_setup->tx_data == NULL){ + if (sspdat[sspnum].dataword == 0){ + SSP_SendData(SSPx, 0xFF); + xf_setup->tx_cnt++; + } else { + SSP_SendData(SSPx, 0xFFFF); + xf_setup->tx_cnt += 2; + } + } else { + if (sspdat[sspnum].dataword == 0){ + SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt))); + xf_setup->tx_cnt++; + } else { + SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt))); + xf_setup->tx_cnt += 2; + } + } + + // Check overrun error + if ((tmp = SSPx->RIS) & SSP_RIS_ROR){ + // update status + xf_setup->status |= SSP_STAT_ERROR; + // Callback + if (xf_setup->callback != NULL){ + xf_setup->callback(); + } + return; + } + + // Check for any data available in RX FIFO + while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (xf_setup->rx_data != NULL) + { + if (sspdat[sspnum].dataword == 0){ + *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp; + } else { + *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp; + } + } + // Increase counter + if (sspdat[sspnum].dataword == 0){ + xf_setup->rx_cnt++; + } else { + xf_setup->rx_cnt += 2; + } + } + } + } + + // If there more data to sent or receive + if ((xf_setup->rx_cnt != xf_setup->length) || (xf_setup->tx_cnt != xf_setup->length)){ + // Enable all interrupt + SSPx->IMSC = SSP_IMSC_BITMASK; + } else { + // Save status + xf_setup->status = SSP_STAT_DONE; + // Callback + if (xf_setup->callback != NULL){ + xf_setup->callback(); + } + } +} + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup SSP_Public_Functions + * @{ + */ + +/*********************************************************************//** + * @brief Setup clock rate for SSP device + * @param[in] SSPx SSP peripheral definition, should be + * SSP0 or SSP1. + * @param[in] target_clock : clock of SSP (Hz) + * @return None + ***********************************************************************/ +void SSP_SetClock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock) +{ + uint32_t prescale, cr0_div, cmp_clk, ssp_clk; + + CHECK_PARAM(PARAM_SSPx(SSPx)); + + /* The SSP clock is derived from the (main system oscillator / 2), + so compute the best divider from that clock */ + if (SSPx == LPC_SSP0){ + ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0); + } else if (SSPx == LPC_SSP1) { + ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1); + } else { + return; + } + + /* Find closest divider to get at or under the target frequency. + Use smallest prescale possible and rely on the divider to get + the closest target frequency */ + cr0_div = 0; + cmp_clk = 0xFFFFFFFF; + prescale = 2; + while (cmp_clk > target_clock) + { + cmp_clk = ssp_clk / ((cr0_div + 1) * prescale); + if (cmp_clk > target_clock) + { + cr0_div++; + if (cr0_div > 0xFF) + { + cr0_div = 0; + prescale += 2; + } + } + } + + /* Write computed prescaler and divider back to register */ + SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK; + SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK; + SSPx->CPSR = prescale & SSP_CPSR_BITMASK; +} + + +/*********************************************************************//** + * @brief De-initializes the SSPx peripheral registers to their +* default reset values. + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @return None + **********************************************************************/ +void SSP_DeInit(LPC_SSP_TypeDef* SSPx) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + + if (SSPx == LPC_SSP0){ + /* Set up clock and power for SSP0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, DISABLE); + } else if (SSPx == LPC_SSP1) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, DISABLE); + } +} + + + +/********************************************************************//** + * @brief Initializes the SSPx peripheral according to the specified +* parameters in the SSP_ConfigStruct. + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] SSP_ConfigStruct Pointer to a SSP_CFG_Type structure +* that contains the configuration information for the +* specified SSP peripheral. + * @return None + *********************************************************************/ +void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct) +{ + uint32_t tmp; + + CHECK_PARAM(PARAM_SSPx(SSPx)); + + if(SSPx == LPC_SSP0) { + /* Set up clock and power for SSP0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, ENABLE); + } else if(SSPx == LPC_SSP1) { + /* Set up clock and power for SSP1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, ENABLE); + } else { + return; + } + + /* Configure SSP, interrupt is disable, LoopBack mode is disable, + * SSP is disable, Slave output is disable as default + */ + tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \ + | (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit)) + & SSP_CR0_BITMASK; + // write back to SSP control register + SSPx->CR0 = tmp; + tmp = SSP_getNum(SSPx); + if (SSP_ConfigStruct->Databit > SSP_DATABIT_8){ + sspdat[tmp].dataword = 1; + } else { + sspdat[tmp].dataword = 0; + } + + tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK; + // Write back to CR1 + SSPx->CR1 = tmp; + + // Set clock rate for SSP peripheral + SSP_SetClock(SSPx, SSP_ConfigStruct->ClockRate); +} + + + +/*****************************************************************************//** +* @brief Fills each SSP_InitStruct member with its default value: +* - CPHA = SSP_CPHA_FIRST +* - CPOL = SSP_CPOL_HI +* - ClockRate = 1000000 +* - Databit = SSP_DATABIT_8 +* - Mode = SSP_MASTER_MODE +* - FrameFormat = SSP_FRAME_SSP +* @param[in] SSP_InitStruct Pointer to a SSP_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct) +{ + SSP_InitStruct->CPHA = SSP_CPHA_FIRST; + SSP_InitStruct->CPOL = SSP_CPOL_HI; + SSP_InitStruct->ClockRate = 1000000; + SSP_InitStruct->Databit = SSP_DATABIT_8; + SSP_InitStruct->Mode = SSP_MASTER_MODE; + SSP_InitStruct->FrameFormat = SSP_FRAME_SPI; +} + + +/*********************************************************************//** + * @brief Enable or disable SSP peripheral's operation + * @param[in] SSPx SSP peripheral, should be SSP0 or SSP1 + * @param[in] NewState New State of SSPx peripheral's operation + * @return none + **********************************************************************/ +void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + SSPx->CR1 |= SSP_CR1_SSP_EN; + } + else + { + SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK; + } +} + + + +/*********************************************************************//** + * @brief Enable or disable Loop Back mode function in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] NewState New State of Loop Back mode, should be: + * - ENABLE: Enable this function + * - DISABLE: Disable this function + * @return None + **********************************************************************/ +void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + SSPx->CR1 |= SSP_CR1_LBM_EN; + } + else + { + SSPx->CR1 &= (~SSP_CR1_LBM_EN) & SSP_CR1_BITMASK; + } +} + + + +/*********************************************************************//** + * @brief Enable or disable Slave Output function in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] NewState New State of Slave Output function, should be: + * - ENABLE: Slave Output in normal operation + * - DISABLE: Slave Output is disabled. This blocks + * SSP controller from driving the transmit data + * line (MISO) + * Note: This function is available when SSP peripheral in Slave mode + * @return None + **********************************************************************/ +void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + SSPx->CR1 &= (~SSP_CR1_SO_DISABLE) & SSP_CR1_BITMASK; + } + else + { + SSPx->CR1 |= SSP_CR1_SO_DISABLE; + } +} + + + +/*********************************************************************//** + * @brief Transmit a single data through SSPx peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP + * @param[in] Data Data to transmit (must be 16 or 8-bit long, + * this depend on SSP data bit number configured) + * @return none + **********************************************************************/ +void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + + SSPx->DR = SSP_DR_BITMASK(Data); +} + + + +/*********************************************************************//** + * @brief Receive a single data from SSPx peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP + * @return Data received (16-bit long) + **********************************************************************/ +uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + + return ((uint16_t) (SSP_DR_BITMASK(SSPx->DR))); +} + +/*********************************************************************//** + * @brief SSP Read write data function + * @param[in] SSPx Pointer to SSP peripheral, should be SSP0 or SSP1 + * @param[in] dataCfg Pointer to a SSP_DATA_SETUP_Type structure that + * contains specified information about transmit + * data configuration. + * @param[in] xfType Transfer type, should be: + * - SSP_TRANSFER_POLLING: Polling mode + * - SSP_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 SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \ + SSP_TRANSFER_Type xfType) +{ + uint8_t *rdata8=NULL; + uint8_t *wdata8=NULL; + uint16_t *rdata16=NULL; + uint16_t *wdata16=NULL; + uint32_t stat; + uint32_t tmp; + int32_t sspnum; + int32_t dataword; + + dataCfg->rx_cnt = 0; + dataCfg->tx_cnt = 0; + dataCfg->status = 0; + + + /* Clear all remaining data in RX FIFO */ + while (SSPx->SR & SSP_SR_RNE){ + tmp = (uint32_t) SSP_ReceiveData(SSPx); + } + + // Clear status + SSPx->ICR = SSP_ICR_BITMASK; + + sspnum = SSP_getNum(SSPx); + dataword = sspdat[sspnum].dataword; + + // Polling mode ---------------------------------------------------------------------- + if (xfType == SSP_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->tx_cnt != dataCfg->length) || (dataCfg->rx_cnt != dataCfg->length)){ + if ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){ + // Write data to buffer + if(dataCfg->tx_data == NULL){ + if (dataword == 0){ + SSP_SendData(SSPx, 0xFF); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, 0xFFFF); + dataCfg->tx_cnt += 2; + } + } else { + if (dataword == 0){ + SSP_SendData(SSPx, *wdata8); + wdata8++; + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, *wdata16); + wdata16++; + dataCfg->tx_cnt += 2; + } + } + } + + // Check overrun error + if ((stat = SSPx->RIS) & SSP_RIS_ROR){ + // save status and return + dataCfg->status = stat | SSP_STAT_ERROR; + return (-1); + } + + // Check for any data available in RX FIFO + while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (dataCfg->rx_data != NULL) + { + if (dataword == 0){ + *(rdata8) = (uint8_t) tmp; + rdata8++; + } else { + *(rdata16) = (uint16_t) tmp; + rdata16++; + } + } + // Increase counter + if (dataword == 0){ + dataCfg->rx_cnt++; + } else { + dataCfg->rx_cnt += 2; + } + } + } + + // save status + dataCfg->status = SSP_STAT_DONE; + + if (dataCfg->tx_data != NULL){ + return dataCfg->tx_cnt; + } else if (dataCfg->rx_data != NULL){ + return dataCfg->rx_cnt; + } else { + return (0); + } + } + + // Interrupt mode ---------------------------------------------------------------------- + else if (xfType == SSP_TRANSFER_INTERRUPT){ + sspdat[sspnum].inthandler = SSP_IntHandler; + sspdat[sspnum].txrx_setup = (uint32_t)dataCfg; + + while ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){ + // Write data to buffer + if(dataCfg->tx_data == NULL){ + if (sspdat[sspnum].dataword == 0){ + SSP_SendData(SSPx, 0xFF); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, 0xFFFF); + dataCfg->tx_cnt += 2; + } + } else { + if (sspdat[sspnum].dataword == 0){ + SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt))); + dataCfg->tx_cnt++; + } else { + SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt))); + dataCfg->tx_cnt += 2; + } + } + + // Check error + if ((stat = SSPx->RIS) & SSP_RIS_ROR){ + // save status and return + dataCfg->status = stat | SSP_STAT_ERROR; + return (-1); + } + + // Check for any data available in RX FIFO + while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){ + // Read data from SSP data + tmp = SSP_ReceiveData(SSPx); + + // Store data to destination + if (dataCfg->rx_data != NULL) + { + if (sspdat[sspnum].dataword == 0){ + *(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp; + } else { + *(uint16_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint16_t) tmp; + } + } + // Increase counter + if (sspdat[sspnum].dataword == 0){ + dataCfg->rx_cnt++; + } else { + dataCfg->rx_cnt += 2; + } + } + } + + // If there more data to sent or receive + if ((dataCfg->rx_cnt != dataCfg->length) || (dataCfg->tx_cnt != dataCfg->length)){ + // Enable all interrupt + SSPx->IMSC = SSP_IMSC_BITMASK; + } else { + // Save status + dataCfg->status = SSP_STAT_DONE; + } + return (0); + } + + return (-1); +} + +/*********************************************************************//** + * @brief Checks whether the specified SSP status flag is set or not + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] FlagType Type of flag to check status, should be one + * of following: + * - SSP_STAT_TXFIFO_EMPTY: TX FIFO is empty + * - SSP_STAT_TXFIFO_NOTFULL: TX FIFO is not full + * - SSP_STAT_RXFIFO_NOTEMPTY: RX FIFO is not empty + * - SSP_STAT_RXFIFO_FULL: RX FIFO is full + * - SSP_STAT_BUSY: SSP peripheral is busy + * @return New State of specified SSP status flag + **********************************************************************/ +FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_STAT(FlagType)); + + return ((SSPx->SR & FlagType) ? SET : RESET); +} + + + +/*********************************************************************//** + * @brief Enable or disable specified interrupt type in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] IntType Interrupt type in SSP peripheral, should be: + * - SSP_INTCFG_ROR: Receive Overrun interrupt + * - SSP_INTCFG_RT: Receive Time out interrupt + * - SSP_INTCFG_RX: RX FIFO is at least half full interrupt + * - SSP_INTCFG_TX: TX FIFO is at least half empty interrupt + * @param[in] NewState New State of specified interrupt type, should be: + * - ENABLE: Enable this interrupt type + * - DISABLE: Disable this interrupt type + * @return None + **********************************************************************/ +void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_INTCFG(IntType)); + + if (NewState == ENABLE) + { + SSPx->IMSC |= IntType; + } + else + { + SSPx->IMSC &= (~IntType) & SSP_IMSC_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Check whether the specified Raw interrupt status flag is + * set or not + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] RawIntType Raw Interrupt Type, should be: + * - SSP_INTSTAT_RAW_ROR: Receive Overrun interrupt + * - SSP_INTSTAT_RAW_RT: Receive Time out interrupt + * - SSP_INTSTAT_RAW_RX: RX FIFO is at least half full interrupt + * - SSP_INTSTAT_RAW_TX: TX FIFO is at least half empty interrupt + * @return New State of specified Raw interrupt status flag in SSP peripheral + * Note: Enabling/Disabling specified interrupt in SSP peripheral does not + * effect to Raw Interrupt Status flag. + **********************************************************************/ +IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_INTSTAT_RAW(RawIntType)); + + return ((SSPx->RIS & RawIntType) ? SET : RESET); +} + + +/*********************************************************************//** + * @brief Check whether the specified interrupt status flag is + * set or not + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] IntType Raw Interrupt Type, should be: + * - SSP_INTSTAT_ROR: Receive Overrun interrupt + * - SSP_INTSTAT_RT: Receive Time out interrupt + * - SSP_INTSTAT_RX: RX FIFO is at least half full interrupt + * - SSP_INTSTAT_TX: TX FIFO is at least half empty interrupt + * @return New State of specified interrupt status flag in SSP peripheral + * Note: Enabling/Disabling specified interrupt in SSP peripheral effects + * to Interrupt Status flag. + **********************************************************************/ +IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_INTSTAT(IntType)); + + return ((SSPx->MIS & IntType) ? SET :RESET); +} + + + +/*********************************************************************//** + * @brief Clear specified interrupt pending in SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] IntType Interrupt pending to clear, should be: + * - SSP_INTCLR_ROR: clears the "frame was received when + * RxFIFO was full" interrupt. + * - SSP_INTCLR_RT: clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt. + * @return None + **********************************************************************/ +void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_INTCLR(IntType)); + + SSPx->ICR = IntType; +} + +/*********************************************************************//** + * @brief Enable/Disable DMA function for SSP peripheral + * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1 + * @param[in] DMAMode Type of DMA, should be: + * - SSP_DMA_TX: DMA for the transmit FIFO + * - SSP_DMA_RX: DMA for the Receive FIFO + * @param[in] NewState New State of DMA function on SSP peripheral, + * should be: + * - ENALBE: Enable this function + * - DISABLE: Disable this function + * @return None + **********************************************************************/ +void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_SSPx(SSPx)); + CHECK_PARAM(PARAM_SSP_DMA(DMAMode)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + SSPx->DMACR |= DMAMode; + } + else + { + SSPx->DMACR &= (~DMAMode) & SSP_DMA_BITMASK; + } +} + +/** + * @brief Standard SSP0 Interrupt handler + * @param[in] None + * @return None + */ +void SSP0_StdIntHandler(void) +{ + // Call relevant handler + sspdat[0].inthandler(LPC_SSP0); +} + +/** + * @brief Standard SSP1 Interrupt handler + * @param[in] None + * @return None + */ +void SSP1_StdIntHandler(void) +{ + // Call relevant handler + sspdat[1].inthandler(LPC_SSP1); +} + +/** + * @} + */ + +#endif /* _SSP */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ +