/*********************************************************************//** * @brief Clear specified interrupt pending in SSP peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Initializes the SSPx peripheral according to the specified * parameters in the SSP_ConfigStruct. * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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_ConfigStruct->Mode & SSP_CR1_BITMASK; // Write back to CR1 SSPx->CR1 = tmp; // Set clock rate for SSP peripheral setSSPclock(SSPx, SSP_ConfigStruct->ClockRate); }
/*********************************************************************//** * @brief De-initializes the SSPx peripheral registers to their * default reset values. * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @return None **********************************************************************/ void SSP_DeInit(LPC_SSPn_Type* SSPx) { CHECK_PARAM(PARAM_SSPx(SSPx)); /* Disable SSP operation*/ SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK; }
/*********************************************************************//** * @brief Check whether the specified interrupt status flag is * set or not * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Check whether the specified Raw interrupt status flag is * set or not * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Checks whether the specified SSP status flag is set or not * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Initializes the SSPx peripheral according to the specified * parameters in the SSP_ConfigStruct. * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @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_SSPn_Type *SSPx, SSP_CFG_Type *SSP_ConfigStruct) { uint32_t tmp; uint32_t prescale, cr0_div, cmp_clk; uint64_t ssp_clk; CHECK_PARAM(PARAM_SSPx(SSPx)); if(SSPx == LPC_SSP0) { /* Set up clock and power for SSP0 module */ //LPC_CGU->BASE_SSP0_CLK = (SRC_PL160M_0<<24) | (1<<11); CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP0); } else if(SSPx == LPC_SSP1) { /* Set up clock and power for SSP1 module */ //LPC_CGU->BASE_SSP1_CLK = (SRC_PL160M_0<<24) | (1<<11); CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP1); } 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_ConfigStruct->Mode & SSP_CR1_BITMASK; // Write back to CR1 SSPx->CR1 = tmp; // Set clock rate for SSP peripheral if(SSPx == LPC_SSP0) ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP0); else ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP1); cr0_div = 0; cmp_clk = 0xFFFFFFFF; prescale = 2; while (cmp_clk > SSP_ConfigStruct->ClockRate) { cmp_clk = ssp_clk / ((cr0_div + 1) * prescale); if (cmp_clk > SSP_ConfigStruct->ClockRate) { 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 Enable or disable Loop Back mode function in SSP peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @param[in] NewState New State of Loop Back mode, should be: * - ENABLE * - DISABLE * @return None **********************************************************************/ void SSP_LoopBackCmd(LPC_SSPn_Type* 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 specified interrupt type in SSP peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @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_SSPn_Type *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 Enable or disable Slave Output function in SSP peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @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_SSPn_Type* 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 De-initializes the SSPx peripheral registers to their * default reset values. * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Enable/Disable DMA function for SSP peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0 :SSP0 peripheral * - LPC_SSP1 :SSP1 peripheral * @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_SSPn_Type *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 Setup clock rate for SSP device * @param[in] SSPx SSP peripheral definition, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @param[in] target_clock : clock of SSP (Hz) * @return None ***********************************************************************/ static void setSSPclock (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 Get Raw Interrupt Status register * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @return Raw Interrupt Status (RIS) register value **********************************************************************/ uint32_t SSP_GetRawIntStatusReg(LPC_SSP_TypeDef *SSPx) { CHECK_PARAM(PARAM_SSPx(SSPx)); return (SSPx->RIS); }
/*********************************************************************//** * @brief Receive a single data from SSPx peripheral * @param[in] SSPx SSP peripheral selected, should be * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Transmit a single data through SSPx peripheral * @param[in] SSPx SSP peripheral selected, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @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 Get data size bit selected * @param[in] SSPx pointer to LPC_SSP_TypeDef structure, should be: * - LPC_SSP0: SSP0 peripheral * - LPC_SSP1: SSP1 peripheral * @return Data size, could be: * - SSP_DATABIT_4: 4 bit transfer * - SSP_DATABIT_5: 5 bit transfer * ... * - SSP_DATABIT_16: 16 bit transfer *******************************************************************************/ uint8_t SSP_GetDataSize(LPC_SSP_TypeDef* SSPx) { CHECK_PARAM(PARAM_SSPx(SSPx)); return (SSPx->CR0 & (0xF)); }