Moved CMSIS and other LPC1768 dependencies

Fixes Arduino IDE builds for 8-bit AVR,
misc: Adafruit NeoPixel currently incompatible with Teensy 3.5-6, blacklisted
This commit is contained in:
Christopher Pepper
2017-08-01 17:19:23 +01:00
committed by Scott Lahteine
parent b55295ad33
commit 4183a249b6
98 changed files with 18 additions and 30240 deletions

View File

@ -0,0 +1,322 @@
/**********************************************************************
* $Id$ debug_frmwrk.c 2010-05-21
*//**
* @file debug_frmwrk.c
* @brief Contains some utilities that used for debugging through UART
* @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.
**********************************************************************/
#include "debug_frmwrk.h"
#include "lpc17xx_pinsel.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 _DBGFWK
/* Debug framework */
void (*_db_msg)(LPC_UART_TypeDef *UARTx, const void *s);
void (*_db_msg_)(LPC_UART_TypeDef *UARTx, const void *s);
void (*_db_char)(LPC_UART_TypeDef *UARTx, uint8_t ch);
void (*_db_dec)(LPC_UART_TypeDef *UARTx, uint8_t decn);
void (*_db_dec_16)(LPC_UART_TypeDef *UARTx, uint16_t decn);
void (*_db_dec_32)(LPC_UART_TypeDef *UARTx, uint32_t decn);
void (*_db_hex)(LPC_UART_TypeDef *UARTx, uint8_t hexn);
void (*_db_hex_16)(LPC_UART_TypeDef *UARTx, uint16_t hexn);
void (*_db_hex_32)(LPC_UART_TypeDef *UARTx, uint32_t hexn);
uint8_t (*_db_get_char)(LPC_UART_TypeDef *UARTx);
/*********************************************************************//**
* @brief Puts a character to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] ch Character to put
* @return None
**********************************************************************/
void UARTPutChar (LPC_UART_TypeDef *UARTx, uint8_t ch)
{
UART_Send(UARTx, &ch, 1, BLOCKING);
}
/*********************************************************************//**
* @brief Get a character to UART port
* @param[in] UARTx Pointer to UART peripheral
* @return character value that returned
**********************************************************************/
uint8_t UARTGetChar (LPC_UART_TypeDef *UARTx)
{
uint8_t tmp = 0;
UART_Receive(UARTx, &tmp, 1, BLOCKING);
return(tmp);
}
/*********************************************************************//**
* @brief Puts a string to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] str string to put
* @return None
**********************************************************************/
void UARTPuts(LPC_UART_TypeDef *UARTx, const void *str)
{
uint8_t *s = (uint8_t *) str;
while (*s)
{
UARTPutChar(UARTx, *s++);
}
}
/*********************************************************************//**
* @brief Puts a string to UART port and print new line
* @param[in] UARTx Pointer to UART peripheral
* @param[in] str String to put
* @return None
**********************************************************************/
void UARTPuts_(LPC_UART_TypeDef *UARTx, const void *str)
{
UARTPuts (UARTx, str);
UARTPuts (UARTx, "\n\r");
}
/*********************************************************************//**
* @brief Puts a decimal number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] decnum Decimal number (8-bit long)
* @return None
**********************************************************************/
void UARTPutDec(LPC_UART_TypeDef *UARTx, uint8_t decnum)
{
uint8_t c1=decnum%10;
uint8_t c2=(decnum/10)%10;
uint8_t c3=(decnum/100)%10;
UARTPutChar(UARTx, '0'+c3);
UARTPutChar(UARTx, '0'+c2);
UARTPutChar(UARTx, '0'+c1);
}
/*********************************************************************//**
* @brief Puts a decimal number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] decnum Decimal number (8-bit long)
* @return None
**********************************************************************/
void UARTPutDec16(LPC_UART_TypeDef *UARTx, uint16_t decnum)
{
uint8_t c1=decnum%10;
uint8_t c2=(decnum/10)%10;
uint8_t c3=(decnum/100)%10;
uint8_t c4=(decnum/1000)%10;
uint8_t c5=(decnum/10000)%10;
UARTPutChar(UARTx, '0'+c5);
UARTPutChar(UARTx, '0'+c4);
UARTPutChar(UARTx, '0'+c3);
UARTPutChar(UARTx, '0'+c2);
UARTPutChar(UARTx, '0'+c1);
}
/*********************************************************************//**
* @brief Puts a decimal number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] decnum Decimal number (8-bit long)
* @return None
**********************************************************************/
void UARTPutDec32(LPC_UART_TypeDef *UARTx, uint32_t decnum)
{
uint8_t c1=decnum%10;
uint8_t c2=(decnum/10)%10;
uint8_t c3=(decnum/100)%10;
uint8_t c4=(decnum/1000)%10;
uint8_t c5=(decnum/10000)%10;
uint8_t c6=(decnum/100000)%10;
uint8_t c7=(decnum/1000000)%10;
uint8_t c8=(decnum/10000000)%10;
uint8_t c9=(decnum/100000000)%10;
uint8_t c10=(decnum/1000000000)%10;
UARTPutChar(UARTx, '0'+c10);
UARTPutChar(UARTx, '0'+c9);
UARTPutChar(UARTx, '0'+c8);
UARTPutChar(UARTx, '0'+c7);
UARTPutChar(UARTx, '0'+c6);
UARTPutChar(UARTx, '0'+c5);
UARTPutChar(UARTx, '0'+c4);
UARTPutChar(UARTx, '0'+c3);
UARTPutChar(UARTx, '0'+c2);
UARTPutChar(UARTx, '0'+c1);
}
/*********************************************************************//**
* @brief Puts a hex number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] hexnum Hex number (8-bit long)
* @return None
**********************************************************************/
void UARTPutHex (LPC_UART_TypeDef *UARTx, uint8_t hexnum)
{
uint8_t nibble, i;
UARTPuts(UARTx, "0x");
i = 1;
do {
nibble = (hexnum >> (4*i)) & 0x0F;
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
} while (i--);
}
/*********************************************************************//**
* @brief Puts a hex number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] hexnum Hex number (16-bit long)
* @return None
**********************************************************************/
void UARTPutHex16 (LPC_UART_TypeDef *UARTx, uint16_t hexnum)
{
uint8_t nibble, i;
UARTPuts(UARTx, "0x");
i = 3;
do {
nibble = (hexnum >> (4*i)) & 0x0F;
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
} while (i--);
}
/*********************************************************************//**
* @brief Puts a hex number to UART port
* @param[in] UARTx Pointer to UART peripheral
* @param[in] hexnum Hex number (32-bit long)
* @return None
**********************************************************************/
void UARTPutHex32 (LPC_UART_TypeDef *UARTx, uint32_t hexnum)
{
uint8_t nibble, i;
UARTPuts(UARTx, "0x");
i = 7;
do {
nibble = (hexnum >> (4*i)) & 0x0F;
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
} while (i--);
}
///*********************************************************************//**
// * @brief print function that supports format as same as printf()
// * function of <stdio.h> library
// * @param[in] None
// * @return None
// **********************************************************************/
//void _printf (const char *format, ...)
//{
// static char buffer[512 + 1];
// va_list vArgs;
// char *tmp;
// va_start(vArgs, format);
// vsprintf((char *)buffer, (char const *)format, vArgs);
// va_end(vArgs);
//
// _DBG(buffer);
//}
/*********************************************************************//**
* @brief Initialize Debug frame work through initializing UART port
* @param[in] None
* @return None
**********************************************************************/
void debug_frmwrk_init(void)
{
UART_CFG_Type UARTConfigStruct;
PINSEL_CFG_Type PinCfg;
#if (USED_UART_DEBUG_PORT==0)
/*
* Initialize UART0 pin connect
*/
PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 2;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 3;
PINSEL_ConfigPin(&PinCfg);
#elif (USED_UART_DEBUG_PORT==1)
/*
* Initialize UART1 pin connect
*/
PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 15;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 16;
PINSEL_ConfigPin(&PinCfg);
#endif
/* Initialize UART Configuration parameter structure to default state:
* Baudrate = 9600bps
* 8 data bit
* 1 Stop bit
* None parity
*/
UART_ConfigStructInit(&UARTConfigStruct);
// Re-configure baudrate to 115200bps
UARTConfigStruct.Baud_rate = 115200;
// Initialize DEBUG_UART_PORT peripheral with given to corresponding parameter
UART_Init((LPC_UART_TypeDef *)DEBUG_UART_PORT, &UARTConfigStruct);
// Enable UART Transmit
UART_TxCmd((LPC_UART_TypeDef *)DEBUG_UART_PORT, ENABLE);
_db_msg = UARTPuts;
_db_msg_ = UARTPuts_;
_db_char = UARTPutChar;
_db_hex = UARTPutHex;
_db_hex_16 = UARTPutHex16;
_db_hex_32 = UARTPutHex32;
_db_dec = UARTPutDec;
_db_dec_16 = UARTPutDec16;
_db_dec_32 = UARTPutDec32;
_db_get_char = UARTGetChar;
}
#endif /*_DBGFWK */
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,358 @@
/**********************************************************************
* $Id$ lpc17xx_adc.c 2010-06-18
*//**
* @file lpc17xx_adc.c
* @brief Contains all functions support for ADC firmware library on LPC17xx
* @version 3.1
* @date 26. July. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, 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 ADC
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_adc.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 _ADC
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup ADC_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initial for ADC
* + Set bit PCADC
* + Set clock for ADC
* + Set Clock Frequency
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] rate ADC conversion rate, should be <=200KHz
* @return None
**********************************************************************/
void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate)
{
uint32_t ADCPClk, temp, tmp;
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_RATE(rate));
// Turn on power and clock
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, ENABLE);
ADCx->ADCR = 0;
//Enable PDN bit
tmp = ADC_CR_PDN;
// Set clock frequency
ADCPClk = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_ADC);
/* The APB clock (PCLK_ADC0) is divided by (CLKDIV+1) to produce the clock for
* A/D converter, which should be less than or equal to 13MHz.
* A fully conversion requires 65 of these clocks.
* ADC clock = PCLK_ADC0 / (CLKDIV + 1);
* ADC rate = ADC clock / 65;
*/
temp = rate * 65;
temp = (ADCPClk * 2 + temp)/(2 * temp) - 1; //get the round value by fomular: (2*A + B)/(2*B)
tmp |= ADC_CR_CLKDIV(temp);
ADCx->ADCR = tmp;
}
/*********************************************************************//**
* @brief Close ADC
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @return None
**********************************************************************/
void ADC_DeInit(LPC_ADC_TypeDef *ADCx)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
if (ADCx->ADCR & ADC_CR_START_MASK) //need to stop START bits before DeInit
ADCx->ADCR &= ~ADC_CR_START_MASK;
// Clear SEL bits
ADCx->ADCR &= ~0xFF;
// Clear PDN bit
ADCx->ADCR &= ~ADC_CR_PDN;
// Turn on power and clock
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, DISABLE);
}
/*********************************************************************//**
* @brief Get Result conversion from A/D data register
* @param[in] channel number which want to read back the result
* @return Result of conversion
*********************************************************************/
uint32_t ADC_GetData(uint32_t channel)
{
uint32_t adc_value;
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
adc_value = *(uint32_t *)((&LPC_ADC->ADDR0) + channel);
return ADC_GDR_RESULT(adc_value);
}
/*********************************************************************//**
* @brief Set start mode for ADC
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] start_mode Start mode choose one of modes in
* 'ADC_START_OPT' enumeration type definition, should be:
* - ADC_START_CONTINUOUS
* - ADC_START_NOW
* - ADC_START_ON_EINT0
* - ADC_START_ON_CAP01
* - ADC_START_ON_MAT01
* - ADC_START_ON_MAT03
* - ADC_START_ON_MAT10
* - ADC_START_ON_MAT11
* @return None
*********************************************************************/
void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));
ADCx->ADCR &= ~ADC_CR_START_MASK;
ADCx->ADCR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);
}
/*********************************************************************//**
* @brief ADC Burst mode setting
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] NewState
* - 1: Set Burst mode
* - 0: reset Burst mode
* @return None
**********************************************************************/
void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
ADCx->ADCR &= ~ADC_CR_BURST;
if (NewState){
ADCx->ADCR |= ADC_CR_BURST;
}
}
/*********************************************************************//**
* @brief Set AD conversion in power mode
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] NewState
* - 1: AD converter is optional
* - 0: AD Converter is in power down mode
* @return None
**********************************************************************/
void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
ADCx->ADCR &= ~ADC_CR_PDN;
if (NewState){
ADCx->ADCR |= ADC_CR_PDN;
}
}
/*********************************************************************//**
* @brief Set Edge start configuration
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING
* 0:ADC_START_ON_RISING
* 1:ADC_START_ON_FALLING
* @return None
**********************************************************************/
void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_START_ON_EDGE_OPT(EdgeOption));
ADCx->ADCR &= ~ADC_CR_EDGE;
if (EdgeOption){
ADCx->ADCR |= ADC_CR_EDGE;
}
}
/*********************************************************************//**
* @brief ADC interrupt configuration
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] IntType: type of interrupt, should be:
* - ADC_ADINTEN0: Interrupt channel 0
* - ADC_ADINTEN1: Interrupt channel 1
* ...
* - ADC_ADINTEN7: Interrupt channel 7
* - ADC_ADGINTEN: Individual channel/global flag done generate an interrupt
* @param[in] NewState:
* - SET : enable ADC interrupt
* - RESET: disable ADC interrupt
* @return None
**********************************************************************/
void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_TYPE_INT_OPT(IntType));
ADCx->ADINTEN &= ~ADC_INTEN_CH(IntType);
if (NewState){
ADCx->ADINTEN |= ADC_INTEN_CH(IntType);
}
}
/*********************************************************************//**
* @brief Enable/Disable ADC channel number
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] Channel channel number
* @param[in] NewState Enable or Disable
*
* @return None
**********************************************************************/
void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(Channel));
if (NewState == ENABLE) {
ADCx->ADCR |= ADC_CR_CH_SEL(Channel);
} else {
if (ADCx->ADCR & ADC_CR_START_MASK) //need to stop START bits before disable channel
ADCx->ADCR &= ~ADC_CR_START_MASK;
ADCx->ADCR &= ~ADC_CR_CH_SEL(Channel);
}
}
/*********************************************************************//**
* @brief Get ADC result
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] channel: channel number, should be 0...7
* @return Data conversion
**********************************************************************/
uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel)
{
uint32_t adc_value;
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
adc_value = *(uint32_t *) ((&ADCx->ADDR0) + channel);
return ADC_DR_RESULT(adc_value);
}
/*********************************************************************//**
* @brief Get ADC Chanel status from ADC data register
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] channel: channel number, should be 0..7
* @param[in] StatusType
* 0:Burst status
* 1:Done status
* @return SET / RESET
**********************************************************************/
FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType)
{
uint32_t temp;
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
temp = *(uint32_t *) ((&ADCx->ADDR0) + channel);
if (StatusType) {
temp &= ADC_DR_DONE_FLAG;
}else{
temp &= ADC_DR_OVERRUN_FLAG;
}
if (temp) {
return SET;
} else {
return RESET;
}
}
/*********************************************************************//**
* @brief Get ADC Data from AD Global register
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @return Result of conversion
**********************************************************************/
uint32_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx)
{
CHECK_PARAM(PARAM_ADCx(ADCx));
return ((uint32_t)(ADCx->ADGDR));
}
/*********************************************************************//**
* @brief Get ADC Chanel status from AD global data register
* @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC
* @param[in] StatusType
* 0:Burst status
* 1:Done status
* @return SET / RESET
**********************************************************************/
FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType)
{
uint32_t temp;
CHECK_PARAM(PARAM_ADCx(ADCx));
CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
temp = ADCx->ADGDR;
if (StatusType){
temp &= ADC_DR_DONE_FLAG;
}else{
temp &= ADC_DR_OVERRUN_FLAG;
}
if (temp){
return SET;
}else{
return RESET;
}
}
/**
* @}
*/
#endif /* _ADC */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,350 @@
/**********************************************************************
* $Id$ lpc17xx_clkpwr.c 2010-06-18
*//**
* @file lpc17xx_clkpwr.c
* @brief Contains all functions support for Clock and Power Control
* firmware library on LPC17xx
* @version 3.0
* @date 18. June. 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 CLKPWR
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_clkpwr.h"
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup CLKPWR_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Set value of each Peripheral Clock Selection
* @param[in] ClkType Peripheral Clock Selection of each type,
* should be one of the following:
* - CLKPWR_PCLKSEL_WDT : WDT
- CLKPWR_PCLKSEL_TIMER0 : Timer 0
- CLKPWR_PCLKSEL_TIMER1 : Timer 1
- CLKPWR_PCLKSEL_UART0 : UART 0
- CLKPWR_PCLKSEL_UART1 : UART 1
- CLKPWR_PCLKSEL_PWM1 : PWM 1
- CLKPWR_PCLKSEL_I2C0 : I2C 0
- CLKPWR_PCLKSEL_SPI : SPI
- CLKPWR_PCLKSEL_SSP1 : SSP 1
- CLKPWR_PCLKSEL_DAC : DAC
- CLKPWR_PCLKSEL_ADC : ADC
- CLKPWR_PCLKSEL_CAN1 : CAN 1
- CLKPWR_PCLKSEL_CAN2 : CAN 2
- CLKPWR_PCLKSEL_ACF : ACF
- CLKPWR_PCLKSEL_QEI : QEI
- CLKPWR_PCLKSEL_PCB : PCB
- CLKPWR_PCLKSEL_I2C1 : I2C 1
- CLKPWR_PCLKSEL_SSP0 : SSP 0
- CLKPWR_PCLKSEL_TIMER2 : Timer 2
- CLKPWR_PCLKSEL_TIMER3 : Timer 3
- CLKPWR_PCLKSEL_UART2 : UART 2
- CLKPWR_PCLKSEL_UART3 : UART 3
- CLKPWR_PCLKSEL_I2C2 : I2C 2
- CLKPWR_PCLKSEL_I2S : I2S
- CLKPWR_PCLKSEL_RIT : RIT
- CLKPWR_PCLKSEL_SYSCON : SYSCON
- CLKPWR_PCLKSEL_MC : MC
* @param[in] DivVal Value of divider, should be:
* - CLKPWR_PCLKSEL_CCLK_DIV_4 : PCLK_peripheral = CCLK/4
* - CLKPWR_PCLKSEL_CCLK_DIV_1 : PCLK_peripheral = CCLK/1
* - CLKPWR_PCLKSEL_CCLK_DIV_2 : PCLK_peripheral = CCLK/2
*
* @return none
**********************************************************************/
void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal)
{
uint32_t bitpos;
bitpos = (ClkType < 32) ? (ClkType) : (ClkType - 32);
/* PCLKSEL0 selected */
if (ClkType < 32)
{
/* Clear two bit at bit position */
LPC_SC->PCLKSEL0 &= (~(CLKPWR_PCLKSEL_BITMASK(bitpos)));
/* Set two selected bit */
LPC_SC->PCLKSEL0 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
}
/* PCLKSEL1 selected */
else
{
/* Clear two bit at bit position */
LPC_SC->PCLKSEL1 &= ~(CLKPWR_PCLKSEL_BITMASK(bitpos));
/* Set two selected bit */
LPC_SC->PCLKSEL1 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
}
}
/*********************************************************************//**
* @brief Get current value of each Peripheral Clock Selection
* @param[in] ClkType Peripheral Clock Selection of each type,
* should be one of the following:
* - CLKPWR_PCLKSEL_WDT : WDT
- CLKPWR_PCLKSEL_TIMER0 : Timer 0
- CLKPWR_PCLKSEL_TIMER1 : Timer 1
- CLKPWR_PCLKSEL_UART0 : UART 0
- CLKPWR_PCLKSEL_UART1 : UART 1
- CLKPWR_PCLKSEL_PWM1 : PWM 1
- CLKPWR_PCLKSEL_I2C0 : I2C 0
- CLKPWR_PCLKSEL_SPI : SPI
- CLKPWR_PCLKSEL_SSP1 : SSP 1
- CLKPWR_PCLKSEL_DAC : DAC
- CLKPWR_PCLKSEL_ADC : ADC
- CLKPWR_PCLKSEL_CAN1 : CAN 1
- CLKPWR_PCLKSEL_CAN2 : CAN 2
- CLKPWR_PCLKSEL_ACF : ACF
- CLKPWR_PCLKSEL_QEI : QEI
- CLKPWR_PCLKSEL_PCB : PCB
- CLKPWR_PCLKSEL_I2C1 : I2C 1
- CLKPWR_PCLKSEL_SSP0 : SSP 0
- CLKPWR_PCLKSEL_TIMER2 : Timer 2
- CLKPWR_PCLKSEL_TIMER3 : Timer 3
- CLKPWR_PCLKSEL_UART2 : UART 2
- CLKPWR_PCLKSEL_UART3 : UART 3
- CLKPWR_PCLKSEL_I2C2 : I2C 2
- CLKPWR_PCLKSEL_I2S : I2S
- CLKPWR_PCLKSEL_RIT : RIT
- CLKPWR_PCLKSEL_SYSCON : SYSCON
- CLKPWR_PCLKSEL_MC : MC
* @return Value of Selected Peripheral Clock Selection
**********************************************************************/
uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType)
{
uint32_t bitpos, retval;
if (ClkType < 32)
{
bitpos = ClkType;
retval = LPC_SC->PCLKSEL0;
}
else
{
bitpos = ClkType - 32;
retval = LPC_SC->PCLKSEL1;
}
retval = CLKPWR_PCLKSEL_GET(bitpos, retval);
return retval;
}
/*********************************************************************//**
* @brief Get current value of each Peripheral Clock
* @param[in] ClkType Peripheral Clock Selection of each type,
* should be one of the following:
* - CLKPWR_PCLKSEL_WDT : WDT
- CLKPWR_PCLKSEL_TIMER0 : Timer 0
- CLKPWR_PCLKSEL_TIMER1 : Timer 1
- CLKPWR_PCLKSEL_UART0 : UART 0
- CLKPWR_PCLKSEL_UART1 : UART 1
- CLKPWR_PCLKSEL_PWM1 : PWM 1
- CLKPWR_PCLKSEL_I2C0 : I2C 0
- CLKPWR_PCLKSEL_SPI : SPI
- CLKPWR_PCLKSEL_SSP1 : SSP 1
- CLKPWR_PCLKSEL_DAC : DAC
- CLKPWR_PCLKSEL_ADC : ADC
- CLKPWR_PCLKSEL_CAN1 : CAN 1
- CLKPWR_PCLKSEL_CAN2 : CAN 2
- CLKPWR_PCLKSEL_ACF : ACF
- CLKPWR_PCLKSEL_QEI : QEI
- CLKPWR_PCLKSEL_PCB : PCB
- CLKPWR_PCLKSEL_I2C1 : I2C 1
- CLKPWR_PCLKSEL_SSP0 : SSP 0
- CLKPWR_PCLKSEL_TIMER2 : Timer 2
- CLKPWR_PCLKSEL_TIMER3 : Timer 3
- CLKPWR_PCLKSEL_UART2 : UART 2
- CLKPWR_PCLKSEL_UART3 : UART 3
- CLKPWR_PCLKSEL_I2C2 : I2C 2
- CLKPWR_PCLKSEL_I2S : I2S
- CLKPWR_PCLKSEL_RIT : RIT
- CLKPWR_PCLKSEL_SYSCON : SYSCON
- CLKPWR_PCLKSEL_MC : MC
* @return Value of Selected Peripheral Clock
**********************************************************************/
uint32_t CLKPWR_GetPCLK (uint32_t ClkType)
{
uint32_t retval, div;
retval = SystemCoreClock;
div = CLKPWR_GetPCLKSEL(ClkType);
switch (div)
{
case 0:
div = 4;
break;
case 1:
div = 1;
break;
case 2:
div = 2;
break;
case 3:
div = 8;
break;
}
retval /= div;
return retval;
}
/*********************************************************************//**
* @brief Configure power supply for each peripheral according to NewState
* @param[in] PPType Type of peripheral used to enable power,
* should be one of the following:
* - CLKPWR_PCONP_PCTIM0 : Timer 0
- CLKPWR_PCONP_PCTIM1 : Timer 1
- CLKPWR_PCONP_PCUART0 : UART 0
- CLKPWR_PCONP_PCUART1 : UART 1
- CLKPWR_PCONP_PCPWM1 : PWM 1
- CLKPWR_PCONP_PCI2C0 : I2C 0
- CLKPWR_PCONP_PCSPI : SPI
- CLKPWR_PCONP_PCRTC : RTC
- CLKPWR_PCONP_PCSSP1 : SSP 1
- CLKPWR_PCONP_PCAD : ADC
- CLKPWR_PCONP_PCAN1 : CAN 1
- CLKPWR_PCONP_PCAN2 : CAN 2
- CLKPWR_PCONP_PCGPIO : GPIO
- CLKPWR_PCONP_PCRIT : RIT
- CLKPWR_PCONP_PCMC : MC
- CLKPWR_PCONP_PCQEI : QEI
- CLKPWR_PCONP_PCI2C1 : I2C 1
- CLKPWR_PCONP_PCSSP0 : SSP 0
- CLKPWR_PCONP_PCTIM2 : Timer 2
- CLKPWR_PCONP_PCTIM3 : Timer 3
- CLKPWR_PCONP_PCUART2 : UART 2
- CLKPWR_PCONP_PCUART3 : UART 3
- CLKPWR_PCONP_PCI2C2 : I2C 2
- CLKPWR_PCONP_PCI2S : I2S
- CLKPWR_PCONP_PCGPDMA : GPDMA
- CLKPWR_PCONP_PCENET : Ethernet
- CLKPWR_PCONP_PCUSB : USB
*
* @param[in] NewState New state of Peripheral Power, should be:
* - ENABLE : Enable power for this peripheral
* - DISABLE : Disable power for this peripheral
*
* @return none
**********************************************************************/
void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState)
{
if (NewState == ENABLE)
{
LPC_SC->PCONP |= PPType & CLKPWR_PCONP_BITMASK;
}
else if (NewState == DISABLE)
{
LPC_SC->PCONP &= (~PPType) & CLKPWR_PCONP_BITMASK;
}
}
/*********************************************************************//**
* @brief Enter Sleep mode with co-operated instruction by the Cortex-M3.
* @param[in] None
* @return None
**********************************************************************/
void CLKPWR_Sleep(void)
{
LPC_SC->PCON = 0x00;
/* Sleep Mode*/
__WFI();
}
/*********************************************************************//**
* @brief Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.
* @param[in] None
* @return None
**********************************************************************/
void CLKPWR_DeepSleep(void)
{
/* Deep-Sleep Mode, set SLEEPDEEP bit */
SCB->SCR = 0x4;
LPC_SC->PCON = 0x00;
/* Deep Sleep Mode*/
__WFI();
}
/*********************************************************************//**
* @brief Enter Power Down mode with co-operated instruction by the Cortex-M3.
* @param[in] None
* @return None
**********************************************************************/
void CLKPWR_PowerDown(void)
{
/* Deep-Sleep Mode, set SLEEPDEEP bit */
SCB->SCR = 0x4;
LPC_SC->PCON = 0x01;
/* Power Down Mode*/
__WFI();
}
/*********************************************************************//**
* @brief Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.
* @param[in] None
* @return None
**********************************************************************/
void CLKPWR_DeepPowerDown(void)
{
/* Deep-Sleep Mode, set SLEEPDEEP bit */
SCB->SCR = 0x4;
LPC_SC->PCON = 0x03;
/* Deep Power Down Mode*/
__WFI();
}
/**
* @}
*/
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,151 @@
/**********************************************************************
* $Id$ lpc17xx_dac.c 2010-05-21
*//**
* @file lpc17xx_dac.c
* @brief Contains all functions support for DAC 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 DAC
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_dac.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 _DAC
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup DAC_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initial ADC configuration
* - Maximum current is 700 uA
* - Value to AOUT is 0
* @param[in] DACx pointer to LPC_DAC_TypeDef, should be: LPC_DAC
* @return None
***********************************************************************/
void DAC_Init(LPC_DAC_TypeDef *DACx)
{
CHECK_PARAM(PARAM_DACx(DACx));
/* Set default clock divider for DAC */
// CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_DAC, CLKPWR_PCLKSEL_CCLK_DIV_4);
//Set maximum current output
DAC_SetBias(LPC_DAC,DAC_MAX_CURRENT_700uA);
}
/*********************************************************************//**
* @brief Update value to DAC
* @param[in] DACx pointer to LPC_DAC_TypeDef, should be: LPC_DAC
* @param[in] dac_value : value 10 bit to be converted to output
* @return None
***********************************************************************/
void DAC_UpdateValue (LPC_DAC_TypeDef *DACx,uint32_t dac_value)
{
uint32_t tmp;
CHECK_PARAM(PARAM_DACx(DACx));
tmp = DACx->DACR & DAC_BIAS_EN;
tmp |= DAC_VALUE(dac_value);
// Update value
DACx->DACR = tmp;
}
/*********************************************************************//**
* @brief Set Maximum current for DAC
* @param[in] DACx pointer to LPC_DAC_TypeDef, should be: LPC_DAC
* @param[in] bias : 0 is 700 uA
* 1 350 uA
* @return None
***********************************************************************/
void DAC_SetBias (LPC_DAC_TypeDef *DACx,uint32_t bias)
{
CHECK_PARAM(PARAM_DAC_CURRENT_OPT(bias));
DACx->DACR &=~DAC_BIAS_EN;
if (bias == DAC_MAX_CURRENT_350uA)
{
DACx->DACR |= DAC_BIAS_EN;
}
}
/*********************************************************************//**
* @brief To enable the DMA operation and control DMA timer
* @param[in] DACx pointer to LPC_DAC_TypeDef, should be: LPC_DAC
* @param[in] DAC_ConverterConfigStruct pointer to DAC_CONVERTER_CFG_Type
* - DBLBUF_ENA : enable/disable DACR double buffering feature
* - CNT_ENA : enable/disable timer out counter
* - DMA_ENA : enable/disable DMA access
* @return None
***********************************************************************/
void DAC_ConfigDAConverterControl (LPC_DAC_TypeDef *DACx,DAC_CONVERTER_CFG_Type *DAC_ConverterConfigStruct)
{
CHECK_PARAM(PARAM_DACx(DACx));
DACx->DACCTRL &= ~DAC_DACCTRL_MASK;
if (DAC_ConverterConfigStruct->DBLBUF_ENA)
DACx->DACCTRL |= DAC_DBLBUF_ENA;
if (DAC_ConverterConfigStruct->CNT_ENA)
DACx->DACCTRL |= DAC_CNT_ENA;
if (DAC_ConverterConfigStruct->DMA_ENA)
DACx->DACCTRL |= DAC_DMA_ENA;
}
/*********************************************************************//**
* @brief Set reload value for interrupt/DMA counter
* @param[in] DACx pointer to LPC_DAC_TypeDef, should be: LPC_DAC
* @param[in] time_out time out to reload for interrupt/DMA counter
* @return None
***********************************************************************/
void DAC_SetDMATimeOut(LPC_DAC_TypeDef *DACx, uint32_t time_out)
{
CHECK_PARAM(PARAM_DACx(DACx));
DACx->DACCNTVAL = DAC_CCNT_VALUE(time_out);
}
/**
* @}
*/
#endif /* _DAC */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,963 @@
/**********************************************************************
* $Id$ lpc17xx_emac.c 2010-05-21
*//**
* @file lpc17xx_emac.c
* @brief Contains all functions support for Ethernet MAC 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 EMAC
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_emac.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 _EMAC
/* Private Variables ---------------------------------------------------------- */
/** @defgroup EMAC_Private_Variables EMAC Private Variables
* @{
*/
/* MII Mgmt Configuration register - Clock divider setting */
const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28, 36, 40, 44, 48, 52, 56, 60, 64};
/* EMAC local DMA Descriptors */
/** Rx Descriptor data array */
static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
/** Rx Status data array - Must be 8-Byte aligned */
#if defined ( __CC_ARM )
static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
#elif defined ( __ICCARM__ )
#pragma data_alignment=8
static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
#elif defined ( __GNUC__ )
static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
#endif
/** Tx Descriptor data array */
static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
/** Tx Status data array */
static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
/* EMAC local DMA buffers */
/** Rx buffer data */
static uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2];
/** Tx buffer data */
static uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2];
/**
* @}
*/
/* Private Functions ---------------------------------------------------------- */
static void rx_descr_init (void);
static void tx_descr_init (void);
static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
static int32_t read_PHY (uint32_t PhyReg);
static void setEmacAddr(uint8_t abStationAddr[]);
static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
/*--------------------------- rx_descr_init ---------------------------------*/
/*********************************************************************//**
* @brief Initializes RX Descriptor
* @param[in] None
* @return None
***********************************************************************/
static void rx_descr_init (void)
{
/* Initialize Receive Descriptor and Status array. */
uint32_t i;
for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
Rx_Desc[i].Packet = (uint32_t)&rx_buf[i];
Rx_Desc[i].Ctrl = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
Rx_Stat[i].Info = 0;
Rx_Stat[i].HashCRC = 0;
}
/* Set EMAC Receive Descriptor Registers. */
LPC_EMAC->RxDescriptor = (uint32_t)&Rx_Desc[0];
LPC_EMAC->RxStatus = (uint32_t)&Rx_Stat[0];
LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
/* Rx Descriptors Point to 0 */
LPC_EMAC->RxConsumeIndex = 0;
}
/*--------------------------- tx_descr_init ---- ----------------------------*/
/*********************************************************************//**
* @brief Initializes TX Descriptor
* @param[in] None
* @return None
***********************************************************************/
static void tx_descr_init (void) {
/* Initialize Transmit Descriptor and Status array. */
uint32_t i;
for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
Tx_Desc[i].Ctrl = 0;
Tx_Stat[i].Info = 0;
}
/* Set EMAC Transmit Descriptor Registers. */
LPC_EMAC->TxDescriptor = (uint32_t)&Tx_Desc[0];
LPC_EMAC->TxStatus = (uint32_t)&Tx_Stat[0];
LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
/* Tx Descriptors Point to 0 */
LPC_EMAC->TxProduceIndex = 0;
}
/*--------------------------- write_PHY -------------------------------------*/
/*********************************************************************//**
* @brief Write value to PHY device
* @param[in] PhyReg: PHY Register address
* @param[in] Value: Value to write
* @return 0 - if success
* 1 - if fail
***********************************************************************/
static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
{
/* Write a data 'Value' to PHY register 'PhyReg'. */
uint32_t tout;
LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
LPC_EMAC->MWTD = Value;
/* Wait until operation completed */
tout = 0;
for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
return (0);
}
}
// Time out!
return (-1);
}
/*--------------------------- read_PHY --------------------------------------*/
/*********************************************************************//**
* @brief Read value from PHY device
* @param[in] PhyReg: PHY Register address
* @return 0 - if success
* 1 - if fail
***********************************************************************/
static int32_t read_PHY (uint32_t PhyReg)
{
/* Read a PHY register 'PhyReg'. */
uint32_t tout;
LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
LPC_EMAC->MCMD = EMAC_MCMD_READ;
/* Wait until operation completed */
tout = 0;
for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) {
if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
LPC_EMAC->MCMD = 0;
return (LPC_EMAC->MRDD);
}
}
// Time out!
return (-1);
}
/*********************************************************************//**
* @brief Set Station MAC address for EMAC module
* @param[in] abStationAddr Pointer to Station address that contains 6-bytes
* of MAC address (should be in order from MAC Address 1 to MAC Address 6)
* @return None
**********************************************************************/
static void setEmacAddr(uint8_t abStationAddr[])
{
/* Set the Ethernet MAC Address registers */
LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
}
/*********************************************************************//**
* @brief Calculates CRC code for number of bytes in the frame
* @param[in] frame_no_fcs Pointer to the first byte of the frame
* @param[in] frame_len length of the frame without the FCS
* @return the CRC as a 32 bit integer
**********************************************************************/
static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
{
int i; // iterator
int j; // another iterator
char byte; // current byte
int crc; // CRC result
int q0, q1, q2, q3; // temporary variables
crc = 0xFFFFFFFF;
for (i = 0; i < frame_len; i++) {
byte = *frame_no_fcs++;
for (j = 0; j < 2; j++) {
if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
q3 = 0x04C11DB7;
} else {
q3 = 0x00000000;
}
if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
q2 = 0x09823B6E;
} else {
q2 = 0x00000000;
}
if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
q1 = 0x130476DC;
} else {
q1 = 0x00000000;
}
if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
q0 = 0x2608EDB8;
} else {
q0 = 0x00000000;
}
crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
byte >>= 4;
}
}
return crc;
}
/* End of Private Functions --------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup EMAC_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initializes the EMAC peripheral according to the specified
* parameters in the EMAC_ConfigStruct.
* @param[in] EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
* that contains the configuration information for the
* specified EMAC peripheral.
* @return None
*
* Note: This function will initialize EMAC module according to procedure below:
* - Remove the soft reset condition from the MAC
* - Configure the PHY via the MIIM interface of the MAC
* - Select RMII mode
* - Configure the transmit and receive DMA engines, including the descriptor arrays
* - Configure the host registers (MAC1,MAC2 etc.) in the MAC
* - Enable the receive and transmit data paths
* In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
* all remain interrupts are disabled
* (Ref. from LPC17xx UM)
**********************************************************************/
Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
{
/* Initialize the EMAC Ethernet controller. */
int32_t regv,tout, tmp;
/* Set up clock and power for Ethernet module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
/* Reset all EMAC internal modules */
LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;
LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;
/* A short delay after reset. */
for (tout = 100; tout; tout--);
/* Initialize MAC control registers. */
LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
/*
* Find the clock that close to desired target clock
*/
tmp = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
if (EMAC_clkdiv[tout] >= tmp) break;
}
tout++;
// Write to MAC configuration register and reset
LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;
// release reset
LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
LPC_EMAC->CLRT = EMAC_CLRT_DEF;
LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;
/* Enable Reduced MII interface. */
LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;
/* Reset Reduced MII Logic. */
// LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;
for (tout = 100; tout; tout--);
LPC_EMAC->SUPP = 0;
/* Put the DP83848C in reset mode */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);
/* Wait for hardware reset to end. */
for (tout = EMAC_PHY_RESP_TOUT; tout>=0; tout--) {
regv = read_PHY (EMAC_PHY_REG_BMCR);
if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
/* Reset complete, device not Power Down. */
break;
}
if (tout == 0){
// Time out, return ERROR
return (ERROR);
}
}
// Set PHY mode
if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
return (ERROR);
}
// Set EMAC address
setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);
/* Initialize Tx and Rx DMA Descriptors */
rx_descr_init ();
tx_descr_init ();
// Set Receive Filter register: enable broadcast and multicast
LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
/* Enable Rx Done and Tx Done interrupt for EMAC */
LPC_EMAC->IntEnable = EMAC_INT_RX_DONE | EMAC_INT_TX_DONE;
/* Reset all interrupts */
LPC_EMAC->IntClear = 0xFFFF;
/* Enable receive and transmit mode of MAC Ethernet core */
LPC_EMAC->Command |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
return SUCCESS;
}
/*********************************************************************//**
* @brief De-initializes the EMAC peripheral registers to their
* default reset values.
* @param[in] None
* @return None
**********************************************************************/
void EMAC_DeInit(void)
{
// Disable all interrupt
LPC_EMAC->IntEnable = 0x00;
// Clear all pending interrupt
LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);
/* TurnOff clock and power for Ethernet module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
}
/*********************************************************************//**
* @brief Check specified PHY status in EMAC peripheral
* @param[in] ulPHYState Specified PHY Status Type, should be:
* - EMAC_PHY_STAT_LINK: Link Status
* - EMAC_PHY_STAT_SPEED: Speed Status
* - EMAC_PHY_STAT_DUP: Duplex Status
* @return Status of specified PHY status (0 or 1).
* (-1) if error.
*
* Note:
* For EMAC_PHY_STAT_LINK, return value:
* - 0: Link Down
* - 1: Link Up
* For EMAC_PHY_STAT_SPEED, return value:
* - 0: 10Mbps
* - 1: 100Mbps
* For EMAC_PHY_STAT_DUP, return value:
* - 0: Half-Duplex
* - 1: Full-Duplex
**********************************************************************/
int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
{
int32_t regv, tmp;
#ifdef MCB_LPC_1768
regv = read_PHY (EMAC_PHY_REG_STS);
switch(ulPHYState){
case EMAC_PHY_STAT_LINK:
tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
break;
case EMAC_PHY_STAT_SPEED:
tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
break;
case EMAC_PHY_STAT_DUP:
tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
break;
#elif defined(IAR_LPC_1768)
/* Use IAR_LPC_1768 board:
* FSZ8721BL doesn't have Status Register
* so we read Basic Mode Status Register (0x01h) instead
*/
regv = read_PHY (EMAC_PHY_REG_BMSR);
switch(ulPHYState){
case EMAC_PHY_STAT_LINK:
tmp = (regv & EMAC_PHY_BMSR_LINK_STATUS) ? 1 : 0;
break;
case EMAC_PHY_STAT_SPEED:
tmp = (regv & EMAC_PHY_SR_100_SPEED) ? 1 : 0;
break;
case EMAC_PHY_STAT_DUP:
tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
break;
#endif
default:
tmp = -1;
break;
}
return (tmp);
}
/*********************************************************************//**
* @brief Set specified PHY mode in EMAC peripheral
* @param[in] ulPHYMode Specified PHY mode, should be:
* - EMAC_MODE_AUTO
* - EMAC_MODE_10M_FULL
* - EMAC_MODE_10M_HALF
* - EMAC_MODE_100M_FULL
* - EMAC_MODE_100M_HALF
* @return Return (0) if no error, otherwise return (-1)
**********************************************************************/
int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
{
int32_t id1, id2, tout;
/* Check if this is a DP83848C PHY. */
id1 = read_PHY (EMAC_PHY_REG_IDR1);
id2 = read_PHY (EMAC_PHY_REG_IDR2);
#ifdef MCB_LPC_1768
if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
switch(ulPHYMode){
case EMAC_MODE_AUTO:
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
#elif defined(IAR_LPC_1768) /* Use IAR LPC1768 KickStart board */
if (((id1 << 16) | id2) == EMAC_KSZ8721BL_ID) {
/* Configure the PHY device */
switch(ulPHYMode){
case EMAC_MODE_AUTO:
/* Use auto-negotiation about the link speed. */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
// write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_AN);
#endif
/* Wait to complete Auto_Negotiation */
for (tout = EMAC_PHY_RESP_TOUT; tout>=0; tout--) {
}
break;
case EMAC_MODE_10M_FULL:
/* Connect at 10MBit full-duplex */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
break;
case EMAC_MODE_10M_HALF:
/* Connect at 10MBit half-duplex */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
break;
case EMAC_MODE_100M_FULL:
/* Connect at 100MBit full-duplex */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
break;
case EMAC_MODE_100M_HALF:
/* Connect at 100MBit half-duplex */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
break;
default:
// un-supported
return (-1);
}
}
// It's not correct module ID
else {
return (-1);
}
// Update EMAC configuration with current PHY status
if (EMAC_UpdatePHYStatus() < 0){
return (-1);
}
// Complete
return (0);
}
/*********************************************************************//**
* @brief Auto-Configures value for the EMAC configuration register to
* match with current PHY mode
* @param[in] None
* @return Return (0) if no error, otherwise return (-1)
*
* Note: The EMAC configuration will be auto-configured:
* - Speed mode.
* - Half/Full duplex mode
**********************************************************************/
int32_t EMAC_UpdatePHYStatus(void)
{
int32_t regv, tout;
/* Check the link status. */
#ifdef MCB_LPC_1768
for (tout = EMAC_PHY_RESP_TOUT; tout>=0; tout--) {
regv = read_PHY (EMAC_PHY_REG_STS);
if (regv & EMAC_PHY_SR_LINK) {
/* Link is on. */
break;
}
if (tout == 0){
// time out
return (-1);
}
}
/* Configure Full/Half Duplex mode. */
if (regv & EMAC_PHY_SR_DUP) {
/* Full duplex is enabled. */
LPC_EMAC->MAC2 |= EMAC_MAC2_FULL_DUP;
LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
LPC_EMAC->IPGT = EMAC_IPGT_FULL_DUP;
} else {
/* Half duplex mode. */
LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
}
if (regv & EMAC_PHY_SR_SPEED) {
/* 10MBit mode. */
LPC_EMAC->SUPP = 0;
} else {
/* 100MBit mode. */
LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
}
#elif defined(IAR_LPC_1768)
for (tout = EMAC_PHY_RESP_TOUT; tout>=0; tout--) {
regv = read_PHY (EMAC_PHY_REG_BMSR);
if (regv & EMAC_PHY_BMSR_LINK_STATUS) {
/* Link is on. */
break;
}
if (tout == 0){
// time out
return (-1);
}
}
/* Configure Full/Half Duplex mode. */
if (regv & EMAC_PHY_SR_FULL_DUP) {
/* Full duplex is enabled. */
LPC_EMAC->MAC2 |= EMAC_MAC2_FULL_DUP;
LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
LPC_EMAC->IPGT = EMAC_IPGT_FULL_DUP;
} else {
/* Half duplex mode. */
LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
}
/* Configure 100MBit/10MBit mode. */
if (!(regv & EMAC_PHY_SR_100_SPEED)) {
/* 10MBit mode. */
LPC_EMAC->SUPP = 0;
} else {
/* 100MBit mode. */
LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
}
#endif
// Complete
return (0);
}
/*********************************************************************//**
* @brief Enable/Disable hash filter functionality for specified destination
* MAC address in EMAC module
* @param[in] dstMAC_addr Pointer to the first MAC destination address, should
* be 6-bytes length, in order LSB to the MSB
* @param[in] NewState New State of this command, should be:
* - ENABLE.
* - DISABLE.
* @return None
*
* Note:
* The standard Ethernet cyclic redundancy check (CRC) function is calculated from
* the 6 byte destination address in the Ethernet frame (this CRC is calculated
* anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
* the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
* the hash table: it is used as an index in the 64 bit HashFilter register that has been
* programmed with accept values. If the selected accept value is 1, the frame is
* accepted.
**********************************************************************/
void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
{
uint32_t *pReg;
uint32_t tmp;
int32_t crc;
// Calculate the CRC from the destination MAC address
crc = emac_CRCCalc(dstMAC_addr, 6);
// Extract the value from CRC to get index value for hash filter table
crc = (crc >> 23) & 0x3F;
pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
: ((uint32_t *)&LPC_EMAC->HashFilterL);
tmp = (crc > 31) ? (crc - 32) : crc;
if (NewState == ENABLE) {
(*pReg) |= (1UL << tmp);
} else {
(*pReg) &= ~(1UL << tmp);
}
// Enable Rx Filter
LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
}
/*********************************************************************//**
* @brief Enable/Disable Filter mode for each specified type EMAC peripheral
* @param[in] ulFilterMode Filter mode, should be:
* - EMAC_RFC_UCAST_EN: all frames of unicast types
* will be accepted
* - EMAC_RFC_BCAST_EN: broadcast frame will be
* accepted
* - EMAC_RFC_MCAST_EN: all frames of multicast
* types will be accepted
* - EMAC_RFC_UCAST_HASH_EN: The imperfect hash
* filter will be applied to unicast addresses
* - EMAC_RFC_MCAST_HASH_EN: The imperfect hash
* filter will be applied to multicast addresses
* - EMAC_RFC_PERFECT_EN: the destination address
* will be compared with the 6 byte station address
* programmed in the station address by the filter
* - EMAC_RFC_MAGP_WOL_EN: the result of the magic
* packet filter will generate a WoL interrupt when
* there is a match
* - EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
* matching filter and the imperfect hash filter will
* generate a WoL interrupt when there is a match
* @param[in] NewState New State of this command, should be:
* - ENABLE
* - DISABLE
* @return None
**********************************************************************/
void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
{
if (NewState == ENABLE){
LPC_EMAC->RxFilterCtrl |= ulFilterMode;
} else {
LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
}
}
/*********************************************************************//**
* @brief Get status of Wake On LAN Filter for each specified
* type in EMAC peripheral, clear this status if it is set
* @param[in] ulWoLMode WoL Filter mode, should be:
* - EMAC_WOL_UCAST: unicast frames caused WoL
* - EMAC_WOL_UCAST: broadcast frame caused WoL
* - EMAC_WOL_MCAST: multicast frame caused WoL
* - EMAC_WOL_UCAST_HASH: unicast frame that passes the
* imperfect hash filter caused WoL
* - EMAC_WOL_MCAST_HASH: multicast frame that passes the
* imperfect hash filter caused WoL
* - EMAC_WOL_PERFECT:perfect address matching filter
* caused WoL
* - EMAC_WOL_RX_FILTER: the receive filter caused WoL
* - EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
* @return SET/RESET
**********************************************************************/
FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
{
if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
LPC_EMAC->RxFilterWoLClear = ulWoLMode;
return SET;
} else {
return RESET;
}
}
/*********************************************************************//**
* @brief Write data to Tx packet data buffer at current index due to
* TxProduceIndex
* @param[in] pDataStruct Pointer to a EMAC_PACKETBUF_Type structure
* data that contain specified information about
* Packet data buffer.
* @return None
**********************************************************************/
void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
{
uint32_t idx,len;
uint32_t *sp,*dp;
idx = LPC_EMAC->TxProduceIndex;
sp = (uint32_t *)pDataStruct->pbDataBuf;
dp = (uint32_t *)Tx_Desc[idx].Packet;
/* Copy frame data to EMAC packet buffers. */
for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
*dp++ = *sp++;
}
Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
}
/*********************************************************************//**
* @brief Read data from Rx packet data buffer at current index due
* to RxConsumeIndex
* @param[in] pDataStruct Pointer to a EMAC_PACKETBUF_Type structure
* data that contain specified information about
* Packet data buffer.
* @return None
**********************************************************************/
void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
{
uint32_t idx, len;
uint32_t *dp, *sp;
idx = LPC_EMAC->RxConsumeIndex;
dp = (uint32_t *)pDataStruct->pbDataBuf;
sp = (uint32_t *)Rx_Desc[idx].Packet;
if (pDataStruct->pbDataBuf != NULL) {
for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
*dp++ = *sp++;
}
}
}
/*********************************************************************//**
* @brief Enable/Disable interrupt for each type in EMAC
* @param[in] ulIntType Interrupt Type, should be:
* - EMAC_INT_RX_OVERRUN: Receive Overrun
* - EMAC_INT_RX_ERR: Receive Error
* - EMAC_INT_RX_FIN: Receive Descriptor Finish
* - EMAC_INT_RX_DONE: Receive Done
* - EMAC_INT_TX_UNDERRUN: Transmit Under-run
* - EMAC_INT_TX_ERR: Transmit Error
* - EMAC_INT_TX_FIN: Transmit descriptor finish
* - EMAC_INT_TX_DONE: Transmit Done
* - EMAC_INT_SOFT_INT: Software interrupt
* - EMAC_INT_WAKEUP: Wakeup interrupt
* @param[in] NewState New State of this function, should be:
* - ENABLE.
* - DISABLE.
* @return None
**********************************************************************/
void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
{
if (NewState == ENABLE) {
LPC_EMAC->IntEnable |= ulIntType;
} else {
LPC_EMAC->IntEnable &= ~(ulIntType);
}
}
/*********************************************************************//**
* @brief Check whether if specified interrupt flag is set or not
* for each interrupt type in EMAC and clear interrupt pending
* if it is set.
* @param[in] ulIntType Interrupt Type, should be:
* - EMAC_INT_RX_OVERRUN: Receive Overrun
* - EMAC_INT_RX_ERR: Receive Error
* - EMAC_INT_RX_FIN: Receive Descriptor Finish
* - EMAC_INT_RX_DONE: Receive Done
* - EMAC_INT_TX_UNDERRUN: Transmit Under-run
* - EMAC_INT_TX_ERR: Transmit Error
* - EMAC_INT_TX_FIN: Transmit descriptor finish
* - EMAC_INT_TX_DONE: Transmit Done
* - EMAC_INT_SOFT_INT: Software interrupt
* - EMAC_INT_WAKEUP: Wakeup interrupt
* @return New state of specified interrupt (SET or RESET)
**********************************************************************/
IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
{
if (LPC_EMAC->IntStatus & ulIntType) {
LPC_EMAC->IntClear = ulIntType;
return SET;
} else {
return RESET;
}
}
/*********************************************************************//**
* @brief Check whether if the current RxConsumeIndex is not equal to the
* current RxProduceIndex.
* @param[in] None
* @return TRUE if they're not equal, otherwise return FALSE
*
* Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
* it means there're available data has been received. They should be read
* out and released the Receive Data Buffer by updating the RxConsumeIndex value.
**********************************************************************/
Bool EMAC_CheckReceiveIndex(void)
{
if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
return TRUE;
} else {
return FALSE;
}
}
/*********************************************************************//**
* @brief Check whether if the current TxProduceIndex is not equal to the
* current RxProduceIndex - 1.
* @param[in] None
* @return TRUE if they're not equal, otherwise return FALSE
*
* Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
* it means the transmit buffer is available and data can be written to transmit
* buffer to be sent.
**********************************************************************/
Bool EMAC_CheckTransmitIndex(void)
{
uint32_t tmp = LPC_EMAC->TxConsumeIndex;
if (LPC_EMAC->TxProduceIndex == ( tmp - 1 ))
{
return FALSE;
}
else if( ( tmp == 0 ) && ( LPC_EMAC->TxProduceIndex == ( EMAC_NUM_TX_FRAG - 1 ) ) )
{
return FALSE;
}
else
{
return TRUE;
}
}
/*********************************************************************//**
* @brief Get current status value of receive data (due to RxConsumeIndex)
* @param[in] ulRxStatType Received Status type, should be one of following:
* - EMAC_RINFO_CTRL_FRAME: Control Frame
* - EMAC_RINFO_VLAN: VLAN Frame
* - EMAC_RINFO_FAIL_FILT: RX Filter Failed
* - EMAC_RINFO_MCAST: Multicast Frame
* - EMAC_RINFO_BCAST: Broadcast Frame
* - EMAC_RINFO_CRC_ERR: CRC Error in Frame
* - EMAC_RINFO_SYM_ERR: Symbol Error from PHY
* - EMAC_RINFO_LEN_ERR: Length Error
* - EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
* - EMAC_RINFO_ALIGN_ERR: Alignment error
* - EMAC_RINFO_OVERRUN: Receive overrun
* - EMAC_RINFO_NO_DESCR: No new Descriptor available
* - EMAC_RINFO_LAST_FLAG: last Fragment in Frame
* - EMAC_RINFO_ERR: Error Occurred (OR of all error)
* @return Current value of receive data (due to RxConsumeIndex)
**********************************************************************/
FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
{
uint32_t idx;
idx = LPC_EMAC->RxConsumeIndex;
return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
}
/*********************************************************************//**
* @brief Get size of current Received data in received buffer (due to
* RxConsumeIndex)
* @param[in] None
* @return Size of received data
**********************************************************************/
uint32_t EMAC_GetReceiveDataSize(void)
{
uint32_t idx;
idx =LPC_EMAC->RxConsumeIndex;
return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
}
/*********************************************************************//**
* @brief Increase the RxConsumeIndex (after reading the Receive buffer
* to release the Receive buffer) and wrap-around the index if
* it reaches the maximum Receive Number
* @param[in] None
* @return None
**********************************************************************/
void EMAC_UpdateRxConsumeIndex(void)
{
// Get current Rx consume index
uint32_t idx = LPC_EMAC->RxConsumeIndex;
/* Release frame from EMAC buffer */
if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
LPC_EMAC->RxConsumeIndex = idx;
}
/*********************************************************************//**
* @brief Increase the TxProduceIndex (after writting to the Transmit buffer
* to enable the Transmit buffer) and wrap-around the index if
* it reaches the maximum Transmit Number
* @param[in] None
* @return None
**********************************************************************/
void EMAC_UpdateTxProduceIndex(void)
{
// Get current Tx produce index
uint32_t idx = LPC_EMAC->TxProduceIndex;
/* Start frame transmission */
if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
LPC_EMAC->TxProduceIndex = idx;
}
/**
* @}
*/
#endif /* _EMAC */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,171 @@
/**********************************************************************
* $Id$ lpc17xx_exti.c 2010-06-18
*//**
* @file lpc17xx_exti.c
* @brief Contains all functions support for External interrupt firmware
* library on LPC17xx
* @version 3.0
* @date 18. June. 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 EXTI
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_exti.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 _EXTI
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup EXTI_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initial for EXT
* - Set EXTINT, EXTMODE, EXTPOLAR registers to default value
* @param[in] None
* @return None
**********************************************************************/
void EXTI_Init(void)
{
LPC_SC->EXTINT = 0xF;
LPC_SC->EXTMODE = 0x0;
LPC_SC->EXTPOLAR = 0x0;
}
/*********************************************************************//**
* @brief Close EXT
* @param[in] None
* @return None
**********************************************************************/
void EXTI_DeInit(void)
{
;
}
/*********************************************************************//**
* @brief Configuration for EXT
* - Set EXTINT, EXTMODE, EXTPOLAR register
* @param[in] EXTICfg Pointer to a EXTI_InitTypeDef structure
* that contains the configuration information for the
* specified external interrupt
* @return None
**********************************************************************/
void EXTI_Config(EXTI_InitTypeDef *EXTICfg)
{
LPC_SC->EXTINT = 0x0;
EXTI_SetMode(EXTICfg->EXTI_Line, EXTICfg->EXTI_Mode);
EXTI_SetPolarity(EXTICfg->EXTI_Line, EXTICfg->EXTI_polarity);
}
/*********************************************************************//**
* @brief Set mode for EXTI pin
* @param[in] EXTILine external interrupt line, should be:
* - EXTI_EINT0: external interrupt line 0
* - EXTI_EINT1: external interrupt line 1
* - EXTI_EINT2: external interrupt line 2
* - EXTI_EINT3: external interrupt line 3
* @param[in] mode external mode, should be:
* - EXTI_MODE_LEVEL_SENSITIVE
* - EXTI_MODE_EDGE_SENSITIVE
* @return None
*********************************************************************/
void EXTI_SetMode(EXTI_LINE_ENUM EXTILine, EXTI_MODE_ENUM mode)
{
if(mode == EXTI_MODE_EDGE_SENSITIVE)
{
LPC_SC->EXTMODE |= (1 << EXTILine);
}
else if(mode == EXTI_MODE_LEVEL_SENSITIVE)
{
LPC_SC->EXTMODE &= ~(1 << EXTILine);
}
}
/*********************************************************************//**
* @brief Set polarity for EXTI pin
* @param[in] EXTILine external interrupt line, should be:
* - EXTI_EINT0: external interrupt line 0
* - EXTI_EINT1: external interrupt line 1
* - EXTI_EINT2: external interrupt line 2
* - EXTI_EINT3: external interrupt line 3
* @param[in] polarity external polarity value, should be:
* - EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE
* - EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE
* @return None
*********************************************************************/
void EXTI_SetPolarity(EXTI_LINE_ENUM EXTILine, EXTI_POLARITY_ENUM polarity)
{
if(polarity == EXTI_POLARITY_HIGH_ACTIVE_OR_RISING_EDGE)
{
LPC_SC->EXTPOLAR |= (1 << EXTILine);
}
else if(polarity == EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE)
{
LPC_SC->EXTPOLAR &= ~(1 << EXTILine);
}
}
/*********************************************************************//**
* @brief Clear External interrupt flag
* @param[in] EXTILine external interrupt line, should be:
* - EXTI_EINT0: external interrupt line 0
* - EXTI_EINT1: external interrupt line 1
* - EXTI_EINT2: external interrupt line 2
* - EXTI_EINT3: external interrupt line 3
* @return None
*********************************************************************/
void EXTI_ClearEXTIFlag(EXTI_LINE_ENUM EXTILine)
{
LPC_SC->EXTINT = (1 << EXTILine);
}
/**
* @}
*/
#endif /* _EXTI */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,463 @@
/**********************************************************************
* $Id$ lpc17xx_gpdma.c 2010-03-21
*//**
* @file lpc17xx_gpdma.c
* @brief Contains all functions support for GPDMA firmware
* library on LPC17xx
* @version 2.1
* @date 25. July. 2011
* @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 GPDMA
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_gpdma.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 _GPDMA
/* Private Variables ---------------------------------------------------------- */
/** @defgroup GPDMA_Private_Variables GPDMA Private Variables
* @{
*/
/**
* @brief Lookup Table of Connection Type matched with
* Peripheral Data (FIFO) register base address
*/
//#ifdef __IAR_SYSTEMS_ICC__
volatile const void *GPDMA_LUTPerAddr[] = {
(&LPC_SSP0->DR), // SSP0 Tx
(&LPC_SSP0->DR), // SSP0 Rx
(&LPC_SSP1->DR), // SSP1 Tx
(&LPC_SSP1->DR), // SSP1 Rx
(&LPC_ADC->ADGDR), // ADC
(&LPC_I2S->I2STXFIFO), // I2S Tx
(&LPC_I2S->I2SRXFIFO), // I2S Rx
(&LPC_DAC->DACR), // DAC
(&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx
(&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx
(&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
(&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
(&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx
(&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx
(&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx
(&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx
(&LPC_TIM0->MR0), // MAT0.0
(&LPC_TIM0->MR1), // MAT0.1
(&LPC_TIM1->MR0), // MAT1.0
(&LPC_TIM1->MR1), // MAT1.1
(&LPC_TIM2->MR0), // MAT2.0
(&LPC_TIM2->MR1), // MAT2.1
(&LPC_TIM3->MR0), // MAT3.0
(&LPC_TIM3->MR1) // MAT3.1
};
//#else
//const uint32_t GPDMA_LUTPerAddr[] = {
// ((uint32_t)&LPC_SSP0->DR), // SSP0 Tx
// ((uint32_t)&LPC_SSP0->DR), // SSP0 Rx
// ((uint32_t)&LPC_SSP1->DR), // SSP1 Tx
// ((uint32_t)&LPC_SSP1->DR), // SSP1 Rx
// ((uint32_t)&LPC_ADC->ADGDR), // ADC
// ((uint32_t)&LPC_I2S->I2STXFIFO), // I2S Tx
// ((uint32_t)&LPC_I2S->I2SRXFIFO), // I2S Rx
// ((uint32_t)&LPC_DAC->DACR), // DAC
// ((uint32_t)&LPC_UART0->/*RBTHDLR.*/THR), // UART0 Tx
// ((uint32_t)&LPC_UART0->/*RBTHDLR.*/RBR), // UART0 Rx
// ((uint32_t)&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
// ((uint32_t)&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
// ((uint32_t)&LPC_UART2->/*RBTHDLR.*/THR), // UART2 Tx
// ((uint32_t)&LPC_UART2->/*RBTHDLR.*/RBR), // UART2 Rx
// ((uint32_t)&LPC_UART3->/*RBTHDLR.*/THR), // UART3 Tx
// ((uint32_t)&LPC_UART3->/*RBTHDLR.*/RBR), // UART3 Rx
// ((uint32_t)&LPC_TIM0->MR0), // MAT0.0
// ((uint32_t)&LPC_TIM0->MR1), // MAT0.1
// ((uint32_t)&LPC_TIM1->MR0), // MAT1.0
// ((uint32_t)&LPC_TIM1->MR1), // MAT1.1
// ((uint32_t)&LPC_TIM2->MR0), // MAT2.0
// ((uint32_t)&LPC_TIM2->MR1), // MAT2.1
// ((uint32_t)&LPC_TIM3->MR0), // MAT3.0
// ((uint32_t)&LPC_TIM3->MR1) // MAT3.1
//};
//#endif
/**
* @brief Lookup Table of GPDMA Channel Number matched with
* GPDMA channel pointer
*/
const LPC_GPDMACH_TypeDef *pGPDMACh[8] = {
LPC_GPDMACH0, // GPDMA Channel 0
LPC_GPDMACH1, // GPDMA Channel 1
LPC_GPDMACH2, // GPDMA Channel 2
LPC_GPDMACH3, // GPDMA Channel 3
LPC_GPDMACH4, // GPDMA Channel 4
LPC_GPDMACH5, // GPDMA Channel 5
LPC_GPDMACH6, // GPDMA Channel 6
LPC_GPDMACH7 // GPDMA Channel 7
};
/**
* @brief Optimized Peripheral Source and Destination burst size
*/
const uint8_t GPDMA_LUTPerBurst[] = {
GPDMA_BSIZE_4, // SSP0 Tx
GPDMA_BSIZE_4, // SSP0 Rx
GPDMA_BSIZE_4, // SSP1 Tx
GPDMA_BSIZE_4, // SSP1 Rx
GPDMA_BSIZE_1, // ADC
GPDMA_BSIZE_32, // I2S channel 0
GPDMA_BSIZE_32, // I2S channel 1
GPDMA_BSIZE_1, // DAC
GPDMA_BSIZE_1, // UART0 Tx
GPDMA_BSIZE_1, // UART0 Rx
GPDMA_BSIZE_1, // UART1 Tx
GPDMA_BSIZE_1, // UART1 Rx
GPDMA_BSIZE_1, // UART2 Tx
GPDMA_BSIZE_1, // UART2 Rx
GPDMA_BSIZE_1, // UART3 Tx
GPDMA_BSIZE_1, // UART3 Rx
GPDMA_BSIZE_1, // MAT0.0
GPDMA_BSIZE_1, // MAT0.1
GPDMA_BSIZE_1, // MAT1.0
GPDMA_BSIZE_1, // MAT1.1
GPDMA_BSIZE_1, // MAT2.0
GPDMA_BSIZE_1, // MAT2.1
GPDMA_BSIZE_1, // MAT3.0
GPDMA_BSIZE_1 // MAT3.1
};
/**
* @brief Optimized Peripheral Source and Destination transfer width
*/
const uint8_t GPDMA_LUTPerWid[] = {
GPDMA_WIDTH_BYTE, // SSP0 Tx
GPDMA_WIDTH_BYTE, // SSP0 Rx
GPDMA_WIDTH_BYTE, // SSP1 Tx
GPDMA_WIDTH_BYTE, // SSP1 Rx
GPDMA_WIDTH_WORD, // ADC
GPDMA_WIDTH_WORD, // I2S channel 0
GPDMA_WIDTH_WORD, // I2S channel 1
GPDMA_WIDTH_BYTE, // DAC
GPDMA_WIDTH_BYTE, // UART0 Tx
GPDMA_WIDTH_BYTE, // UART0 Rx
GPDMA_WIDTH_BYTE, // UART1 Tx
GPDMA_WIDTH_BYTE, // UART1 Rx
GPDMA_WIDTH_BYTE, // UART2 Tx
GPDMA_WIDTH_BYTE, // UART2 Rx
GPDMA_WIDTH_BYTE, // UART3 Tx
GPDMA_WIDTH_BYTE, // UART3 Rx
GPDMA_WIDTH_WORD, // MAT0.0
GPDMA_WIDTH_WORD, // MAT0.1
GPDMA_WIDTH_WORD, // MAT1.0
GPDMA_WIDTH_WORD, // MAT1.1
GPDMA_WIDTH_WORD, // MAT2.0
GPDMA_WIDTH_WORD, // MAT2.1
GPDMA_WIDTH_WORD, // MAT3.0
GPDMA_WIDTH_WORD // MAT3.1
};
/**
* @}
*/
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup GPDMA_Public_Functions
* @{
*/
/********************************************************************//**
* @brief Initialize GPDMA controller
* @param None
* @return None
*********************************************************************/
void GPDMA_Init(void)
{
/* Enable GPDMA clock */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCGPDMA, ENABLE);
// Reset all channel configuration register
LPC_GPDMACH0->DMACCConfig = 0;
LPC_GPDMACH1->DMACCConfig = 0;
LPC_GPDMACH2->DMACCConfig = 0;
LPC_GPDMACH3->DMACCConfig = 0;
LPC_GPDMACH4->DMACCConfig = 0;
LPC_GPDMACH5->DMACCConfig = 0;
LPC_GPDMACH6->DMACCConfig = 0;
LPC_GPDMACH7->DMACCConfig = 0;
/* Clear all DMA interrupt and error flag */
LPC_GPDMA->DMACIntTCClear = 0xFF;
LPC_GPDMA->DMACIntErrClr = 0xFF;
}
/********************************************************************//**
* @brief Setup GPDMA channel peripheral according to the specified
* parameters in the GPDMAChannelConfig.
* @param[in] GPDMAChannelConfig Pointer to a GPDMA_CH_CFG_Type
* structure that contains the configuration
* information for the specified GPDMA channel peripheral.
* @return ERROR if selected channel is enabled before
* or SUCCESS if channel is configured successfully
*********************************************************************/
Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig)
{
LPC_GPDMACH_TypeDef *pDMAch;
uint32_t tmp1, tmp2;
if (LPC_GPDMA->DMACEnbldChns & (GPDMA_DMACEnbldChns_Ch(GPDMAChannelConfig->ChannelNum))) {
// This channel is enabled, return ERROR, need to release this channel first
return ERROR;
}
// Get Channel pointer
pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[GPDMAChannelConfig->ChannelNum];
// Reset the Interrupt status
LPC_GPDMA->DMACIntTCClear = GPDMA_DMACIntTCClear_Ch(GPDMAChannelConfig->ChannelNum);
LPC_GPDMA->DMACIntErrClr = GPDMA_DMACIntErrClr_Ch(GPDMAChannelConfig->ChannelNum);
// Clear DMA configure
pDMAch->DMACCControl = 0x00;
pDMAch->DMACCConfig = 0x00;
/* Assign Linker List Item value */
pDMAch->DMACCLLI = GPDMAChannelConfig->DMALLI;
/* Set value to Channel Control Registers */
switch (GPDMAChannelConfig->TransferType)
{
// Memory to memory
case GPDMA_TRANSFERTYPE_M2M:
// Assign physical source and destination address
pDMAch->DMACCSrcAddr = GPDMAChannelConfig->SrcMemAddr;
pDMAch->DMACCDestAddr = GPDMAChannelConfig->DstMemAddr;
pDMAch->DMACCControl
= GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize) \
| GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_32) \
| GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_32) \
| GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth) \
| GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth) \
| GPDMA_DMACCxControl_SI \
| GPDMA_DMACCxControl_DI \
| GPDMA_DMACCxControl_I;
break;
// Memory to peripheral
case GPDMA_TRANSFERTYPE_M2P:
// Assign physical source
pDMAch->DMACCSrcAddr = GPDMAChannelConfig->SrcMemAddr;
// Assign peripheral destination address
pDMAch->DMACCDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
pDMAch->DMACCControl
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_SI \
| GPDMA_DMACCxControl_I;
break;
// Peripheral to memory
case GPDMA_TRANSFERTYPE_P2M:
// Assign peripheral source address
pDMAch->DMACCSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
// Assign memory destination address
pDMAch->DMACCDestAddr = GPDMAChannelConfig->DstMemAddr;
pDMAch->DMACCControl
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_DI \
| GPDMA_DMACCxControl_I;
break;
// Peripheral to peripheral
case GPDMA_TRANSFERTYPE_P2P:
// Assign peripheral source address
pDMAch->DMACCSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
// Assign peripheral destination address
pDMAch->DMACCDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
pDMAch->DMACCControl
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
| GPDMA_DMACCxControl_I;
break;
// Do not support any more transfer type, return ERROR
default:
return ERROR;
}
/* Re-Configure DMA Request Select for source peripheral */
if (GPDMAChannelConfig->SrcConn > 15)
{
LPC_SC->DMAREQSEL |= (1<<(GPDMAChannelConfig->SrcConn - 16));
} else {
LPC_SC->DMAREQSEL &= ~(1<<(GPDMAChannelConfig->SrcConn - 8));
}
/* Re-Configure DMA Request Select for Destination peripheral */
if (GPDMAChannelConfig->DstConn > 15)
{
LPC_SC->DMAREQSEL |= (1<<(GPDMAChannelConfig->DstConn - 16));
} else {
LPC_SC->DMAREQSEL &= ~(1<<(GPDMAChannelConfig->DstConn - 8));
}
/* Enable DMA channels, little endian */
LPC_GPDMA->DMACConfig = GPDMA_DMACConfig_E;
while (!(LPC_GPDMA->DMACConfig & GPDMA_DMACConfig_E));
// Calculate absolute value for Connection number
tmp1 = GPDMAChannelConfig->SrcConn;
tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
tmp2 = GPDMAChannelConfig->DstConn;
tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
// Configure DMA Channel, enable Error Counter and Terminate counter
pDMAch->DMACCConfig = GPDMA_DMACCxConfig_IE | GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/ \
| GPDMA_DMACCxConfig_TransferType((uint32_t)GPDMAChannelConfig->TransferType) \
| GPDMA_DMACCxConfig_SrcPeripheral(tmp1) \
| GPDMA_DMACCxConfig_DestPeripheral(tmp2);
return SUCCESS;
}
/*********************************************************************//**
* @brief Enable/Disable DMA channel
* @param[in] channelNum GPDMA channel, should be in range from 0 to 7
* @param[in] NewState New State of this command, should be:
* - ENABLE.
* - DISABLE.
* @return None
**********************************************************************/
void GPDMA_ChannelCmd(uint8_t channelNum, FunctionalState NewState)
{
LPC_GPDMACH_TypeDef *pDMAch;
// Get Channel pointer
pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[channelNum];
if (NewState == ENABLE) {
pDMAch->DMACCConfig |= GPDMA_DMACCxConfig_E;
} else {
pDMAch->DMACCConfig &= ~GPDMA_DMACCxConfig_E;
}
}
/*********************************************************************//**
* @brief Check if corresponding channel does have an active interrupt
* request or not
* @param[in] type type of status, should be:
* - GPDMA_STAT_INT: GPDMA Interrupt Status
* - GPDMA_STAT_INTTC: GPDMA Interrupt Terminal Count Request Status
* - GPDMA_STAT_INTERR: GPDMA Interrupt Error Status
* - GPDMA_STAT_RAWINTTC: GPDMA Raw Interrupt Terminal Count Status
* - GPDMA_STAT_RAWINTERR: GPDMA Raw Error Interrupt Status
* - GPDMA_STAT_ENABLED_CH:GPDMA Enabled Channel Status
* @param[in] channel GPDMA channel, should be in range from 0 to 7
* @return IntStatus status of DMA channel interrupt after masking
* Should be:
* - SET: the corresponding channel has no active interrupt request
* - RESET: the corresponding channel does have an active interrupt request
**********************************************************************/
IntStatus GPDMA_IntGetStatus(GPDMA_Status_Type type, uint8_t channel)
{
CHECK_PARAM(PARAM_GPDMA_STAT(type));
CHECK_PARAM(PARAM_GPDMA_CHANNEL(channel));
switch (type)
{
case GPDMA_STAT_INT: //check status of DMA channel interrupts
if (LPC_GPDMA->DMACIntStat & (GPDMA_DMACIntStat_Ch(channel)))
return SET;
return RESET;
case GPDMA_STAT_INTTC: // check terminal count interrupt request status for DMA
if (LPC_GPDMA->DMACIntTCStat & GPDMA_DMACIntTCStat_Ch(channel))
return SET;
return RESET;
case GPDMA_STAT_INTERR: //check interrupt status for DMA channels
if (LPC_GPDMA->DMACIntErrStat & GPDMA_DMACIntTCClear_Ch(channel))
return SET;
return RESET;
case GPDMA_STAT_RAWINTTC: //check status of the terminal count interrupt for DMA channels
if (LPC_GPDMA->DMACRawIntErrStat & GPDMA_DMACRawIntTCStat_Ch(channel))
return SET;
return RESET;
case GPDMA_STAT_RAWINTERR: //check status of the error interrupt for DMA channels
if (LPC_GPDMA->DMACRawIntTCStat & GPDMA_DMACRawIntErrStat_Ch(channel))
return SET;
return RESET;
default: //check enable status for DMA channels
if (LPC_GPDMA->DMACEnbldChns & GPDMA_DMACEnbldChns_Ch(channel))
return SET;
return RESET;
}
}
/*********************************************************************//**
* @brief Clear one or more interrupt requests on DMA channels
* @param[in] type type of interrupt request, should be:
* - GPDMA_STATCLR_INTTC: GPDMA Interrupt Terminal Count Request Clear
* - GPDMA_STATCLR_INTERR: GPDMA Interrupt Error Clear
* @param[in] channel GPDMA channel, should be in range from 0 to 7
* @return None
**********************************************************************/
void GPDMA_ClearIntPending(GPDMA_StateClear_Type type, uint8_t channel)
{
CHECK_PARAM(PARAM_GPDMA_STATCLR(type));
CHECK_PARAM(PARAM_GPDMA_CHANNEL(channel));
if (type == GPDMA_STATCLR_INTTC) // clears the terminal count interrupt request on DMA channel
LPC_GPDMA->DMACIntTCClear = GPDMA_DMACIntTCClear_Ch(channel);
else // clear the error interrupt request
LPC_GPDMA->DMACIntErrClr = GPDMA_DMACIntErrClr_Ch(channel);
}
/**
* @}
*/
#endif /* _GPDMA */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,762 @@
/**********************************************************************
* $Id$ lpc17xx_gpio.c 2010-05-21
*//**
* @file lpc17xx_gpio.c
* @brief Contains all functions support for GPIO 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 GPIO
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_gpio.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 _GPIO
/* Private Functions ---------------------------------------------------------- */
static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum);
static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum);
static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum);
/*********************************************************************//**
* @brief Get pointer to GPIO peripheral due to GPIO port
* @param[in] portNum Port Number value, should be in range from 0 to 4.
* @return Pointer to GPIO peripheral
**********************************************************************/
static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum)
{
LPC_GPIO_TypeDef *pGPIO = NULL;
switch (portNum) {
case 0:
pGPIO = LPC_GPIO0;
break;
case 1:
pGPIO = LPC_GPIO1;
break;
case 2:
pGPIO = LPC_GPIO2;
break;
case 3:
pGPIO = LPC_GPIO3;
break;
case 4:
pGPIO = LPC_GPIO4;
break;
default:
break;
}
return pGPIO;
}
/*********************************************************************//**
* @brief Get pointer to FIO peripheral in halfword accessible style
* due to FIO port
* @param[in] portNum Port Number value, should be in range from 0 to 4.
* @return Pointer to FIO peripheral
**********************************************************************/
static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum)
{
GPIO_HalfWord_TypeDef *pFIO = NULL;
switch (portNum) {
case 0:
pFIO = GPIO0_HalfWord;
break;
case 1:
pFIO = GPIO1_HalfWord;
break;
case 2:
pFIO = GPIO2_HalfWord;
break;
case 3:
pFIO = GPIO3_HalfWord;
break;
case 4:
pFIO = GPIO4_HalfWord;
break;
default:
break;
}
return pFIO;
}
/*********************************************************************//**
* @brief Get pointer to FIO peripheral in byte accessible style
* due to FIO port
* @param[in] portNum Port Number value, should be in range from 0 to 4.
* @return Pointer to FIO peripheral
**********************************************************************/
static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum)
{
GPIO_Byte_TypeDef *pFIO = NULL;
switch (portNum) {
case 0:
pFIO = GPIO0_Byte;
break;
case 1:
pFIO = GPIO1_Byte;
break;
case 2:
pFIO = GPIO2_Byte;
break;
case 3:
pFIO = GPIO3_Byte;
break;
case 4:
pFIO = GPIO4_Byte;
break;
default:
break;
}
return pFIO;
}
/* End of Private Functions --------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup GPIO_Public_Functions
* @{
*/
/* GPIO ------------------------------------------------------------------------------ */
/*********************************************************************//**
* @brief Set Direction for GPIO port.
* @param[in] portNum Port Number value, should be in range from 0 to 4
* @param[in] bitValue Value that contains all bits to set direction,
* in range from 0 to 0xFFFFFFFF.
* example: value 0x5 to set direction for bit 0 and bit 1.
* @param[in] dir Direction value, should be:
* - 0: Input.
* - 1: Output.
* @return None
*
* Note: All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
{
LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
if (pGPIO != NULL) {
// Enable Output
if (dir) {
pGPIO->FIODIR |= bitValue;
}
// Enable Input
else {
pGPIO->FIODIR &= ~bitValue;
}
}
}
/*********************************************************************//**
* @brief Set Value for bits that have output direction on GPIO port.
* @param[in] portNum Port number value, should be in range from 0 to 4
* @param[in] bitValue Value that contains all bits on GPIO to set,
* in range from 0 to 0xFFFFFFFF.
* example: value 0x5 to set bit 0 and bit 1.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
{
LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
if (pGPIO != NULL) {
pGPIO->FIOSET = bitValue;
}
}
/*********************************************************************//**
* @brief Clear Value for bits that have output direction on GPIO port.
* @param[in] portNum Port number value, should be in range from 0 to 4
* @param[in] bitValue Value that contains all bits on GPIO to clear,
* in range from 0 to 0xFFFFFFFF.
* example: value 0x5 to clear bit 0 and bit 1.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)
{
LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
if (pGPIO != NULL) {
pGPIO->FIOCLR = bitValue;
}
}
/*********************************************************************//**
* @brief Read Current state on port pin that have input direction of GPIO
* @param[in] portNum Port number to read value, in range from 0 to 4
* @return Current value of GPIO port.
*
* Note: Return value contain state of each port pin (bit) on that GPIO regardless
* its direction is input or output.
**********************************************************************/
uint32_t GPIO_ReadValue(uint8_t portNum)
{
LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
if (pGPIO != NULL) {
return pGPIO->FIOPIN;
}
return (0);
}
/*********************************************************************//**
* @brief Enable GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13)
* @param[in] portNum Port number to read value, should be: 0 or 2
* @param[in] bitValue Value that contains all bits on GPIO to enable,
* in range from 0 to 0xFFFFFFFF.
* @param[in] edgeState state of edge, should be:
* - 0: Rising edge
* - 1: Falling edge
* @return None
**********************************************************************/
void GPIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState)
{
if((portNum == 0)&&(edgeState == 0))
LPC_GPIOINT->IO0IntEnR = bitValue;
else if ((portNum == 2)&&(edgeState == 0))
LPC_GPIOINT->IO2IntEnR = bitValue;
else if ((portNum == 0)&&(edgeState == 1))
LPC_GPIOINT->IO0IntEnF = bitValue;
else if ((portNum == 2)&&(edgeState == 1))
LPC_GPIOINT->IO2IntEnF = bitValue;
else
//Error
while(1);
}
/*********************************************************************//**
* @brief Get GPIO Interrupt Status (just used for P0.0-P0.30, P2.0-P2.13)
* @param[in] portNum Port number to read value, should be: 0 or 2
* @param[in] pinNum Pin number, should be: 0..30(with port 0) and 0..13
* (with port 2)
* @param[in] edgeState state of edge, should be:
* - 0: Rising edge
* - 1: Falling edge
* @return Bool could be:
* - ENABLE: Interrupt has been generated due to a rising
* edge on P0.0
* - DISABLE: A rising edge has not been detected on P0.0
**********************************************************************/
FunctionalState GPIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState)
{
if((portNum == 0) && (edgeState == 0))//Rising Edge
return ((FunctionalState)(((LPC_GPIOINT->IO0IntStatR)>>pinNum)& 0x1));
else if ((portNum == 2) && (edgeState == 0))
return ((FunctionalState)(((LPC_GPIOINT->IO2IntStatR)>>pinNum)& 0x1));
else if ((portNum == 0) && (edgeState == 1))//Falling Edge
return ((FunctionalState)(((LPC_GPIOINT->IO0IntStatF)>>pinNum)& 0x1));
else if ((portNum == 2) && (edgeState == 1))
return ((FunctionalState)(((LPC_GPIOINT->IO2IntStatF)>>pinNum)& 0x1));
else
//Error
while(1);
}
/*********************************************************************//**
* @brief Clear GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13)
* @param[in] portNum Port number to read value, should be: 0 or 2
* @param[in] bitValue Value that contains all bits on GPIO to enable,
* in range from 0 to 0xFFFFFFFF.
* @return None
**********************************************************************/
void GPIO_ClearInt(uint8_t portNum, uint32_t bitValue)
{
if(portNum == 0)
LPC_GPIOINT->IO0IntClr = bitValue;
else if (portNum == 2)
LPC_GPIOINT->IO2IntClr = bitValue;
else
//Invalid portNum
while(1);
}
/* FIO word accessible ----------------------------------------------------------------- */
/* Stub function for FIO (word-accessible) style */
/**
* @brief The same with GPIO_SetDir()
*/
void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
{
GPIO_SetDir(portNum, bitValue, dir);
}
/**
* @brief The same with GPIO_SetValue()
*/
void FIO_SetValue(uint8_t portNum, uint32_t bitValue)
{
GPIO_SetValue(portNum, bitValue);
}
/**
* @brief The same with GPIO_ClearValue()
*/
void FIO_ClearValue(uint8_t portNum, uint32_t bitValue)
{
GPIO_ClearValue(portNum, bitValue);
}
/**
* @brief The same with GPIO_ReadValue()
*/
uint32_t FIO_ReadValue(uint8_t portNum)
{
return (GPIO_ReadValue(portNum));
}
/**
* @brief The same with GPIO_IntCmd()
*/
void FIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState)
{
GPIO_IntCmd(portNum, bitValue, edgeState);
}
/**
* @brief The same with GPIO_GetIntStatus()
*/
FunctionalState FIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState)
{
return (GPIO_GetIntStatus(portNum, pinNum, edgeState));
}
/**
* @brief The same with GPIO_ClearInt()
*/
void FIO_ClearInt(uint8_t portNum, uint32_t bitValue)
{
GPIO_ClearInt(portNum, bitValue);
}
/*********************************************************************//**
* @brief Set mask value for bits in FIO port
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] bitValue Value that contains all bits in to set,
* in range from 0 to 0xFFFFFFFF.
* @param[in] maskValue Mask value contains state value for each bit:
* - 0: not mask.
* - 1: mask.
* @return None
*
* Note:
* - All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
* - After executing this function, in mask register, value '0' on each bit
* enables an access to the corresponding physical pin via a read or write access,
* while value '1' on bit (masked) that corresponding pin will not be changed
* with write access and if read, will not be reflected in the updated pin.
**********************************************************************/
void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue)
{
LPC_GPIO_TypeDef *pFIO = GPIO_GetPointer(portNum);
if(pFIO != NULL) {
// Mask
if (maskValue){
pFIO->FIOMASK |= bitValue;
}
// Un-mask
else {
pFIO->FIOMASK &= ~bitValue;
}
}
}
/* FIO halfword accessible ------------------------------------------------------------- */
/*********************************************************************//**
* @brief Set direction for FIO port in halfword accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)
* @param[in] bitValue Value that contains all bits in to set direction,
* in range from 0 to 0xFFFF.
* @param[in] dir Direction value, should be:
* - 0: Input.
* - 1: Output.
* @return None
*
* Note: All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir)
{
GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
if(pFIO != NULL) {
// Output direction
if (dir) {
// Upper
if(halfwordNum) {
pFIO->FIODIRU |= bitValue;
}
// lower
else {
pFIO->FIODIRL |= bitValue;
}
}
// Input direction
else {
// Upper
if(halfwordNum) {
pFIO->FIODIRU &= ~bitValue;
}
// lower
else {
pFIO->FIODIRL &= ~bitValue;
}
}
}
}
/*********************************************************************//**
* @brief Set mask value for bits in FIO port in halfword accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)
* @param[in] bitValue Value that contains all bits in to set,
* in range from 0 to 0xFFFF.
* @param[in] maskValue Mask value contains state value for each bit:
* - 0: not mask.
* - 1: mask.
* @return None
*
* Note:
* - All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
* - After executing this function, in mask register, value '0' on each bit
* enables an access to the corresponding physical pin via a read or write access,
* while value '1' on bit (masked) that corresponding pin will not be changed
* with write access and if read, will not be reflected in the updated pin.
**********************************************************************/
void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue)
{
GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
if(pFIO != NULL) {
// Mask
if (maskValue){
// Upper
if(halfwordNum) {
pFIO->FIOMASKU |= bitValue;
}
// lower
else {
pFIO->FIOMASKL |= bitValue;
}
}
// Un-mask
else {
// Upper
if(halfwordNum) {
pFIO->FIOMASKU &= ~bitValue;
}
// lower
else {
pFIO->FIOMASKL &= ~bitValue;
}
}
}
}
/*********************************************************************//**
* @brief Set bits for FIO port in halfword accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)
* @param[in] bitValue Value that contains all bits in to set,
* in range from 0 to 0xFFFF.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)
{
GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
if(pFIO != NULL) {
// Upper
if(halfwordNum) {
pFIO->FIOSETU = bitValue;
}
// lower
else {
pFIO->FIOSETL = bitValue;
}
}
}
/*********************************************************************//**
* @brief Clear bits for FIO port in halfword accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)
* @param[in] bitValue Value that contains all bits in to clear,
* in range from 0 to 0xFFFF.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)
{
GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
if(pFIO != NULL) {
// Upper
if(halfwordNum) {
pFIO->FIOCLRU = bitValue;
}
// lower
else {
pFIO->FIOCLRL = bitValue;
}
}
}
/*********************************************************************//**
* @brief Read Current state on port pin that have input direction of GPIO
* in halfword accessible style.
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)
* @return Current value of FIO port pin of specified halfword.
* Note: Return value contain state of each port pin (bit) on that FIO regardless
* its direction is input or output.
**********************************************************************/
uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum)
{
GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
if(pFIO != NULL) {
// Upper
if(halfwordNum) {
return (pFIO->FIOPINU);
}
// lower
else {
return (pFIO->FIOPINL);
}
}
return (0);
}
/* FIO Byte accessible ------------------------------------------------------------ */
/*********************************************************************//**
* @brief Set direction for FIO port in byte accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] byteNum Byte part number, should be in range from 0 to 3
* @param[in] bitValue Value that contains all bits in to set direction,
* in range from 0 to 0xFF.
* @param[in] dir Direction value, should be:
* - 0: Input.
* - 1: Output.
* @return None
*
* Note: All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir)
{
GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
if(pFIO != NULL) {
// Output direction
if (dir) {
if (byteNum <= 3) {
pFIO->FIODIR[byteNum] |= bitValue;
}
}
// Input direction
else {
if (byteNum <= 3) {
pFIO->FIODIR[byteNum] &= ~bitValue;
}
}
}
}
/*********************************************************************//**
* @brief Set mask value for bits in FIO port in byte accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] byteNum Byte part number, should be in range from 0 to 3
* @param[in] bitValue Value that contains all bits in to set mask,
* in range from 0 to 0xFF.
* @param[in] maskValue Mask value contains state value for each bit:
* - 0: not mask.
* - 1: mask.
* @return None
*
* Note:
* - All remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
* - After executing this function, in mask register, value '0' on each bit
* enables an access to the corresponding physical pin via a read or write access,
* while value '1' on bit (masked) that corresponding pin will not be changed
* with write access and if read, will not be reflected in the updated pin.
**********************************************************************/
void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue)
{
GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
if(pFIO != NULL) {
// Mask
if (maskValue) {
if (byteNum <= 3) {
pFIO->FIOMASK[byteNum] |= bitValue;
}
}
// Un-mask
else {
if (byteNum <= 3) {
pFIO->FIOMASK[byteNum] &= ~bitValue;
}
}
}
}
/*********************************************************************//**
* @brief Set bits for FIO port in byte accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] byteNum Byte part number, should be in range from 0 to 3
* @param[in] bitValue Value that contains all bits in to set,
* in range from 0 to 0xFF.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)
{
GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
if (pFIO != NULL) {
if (byteNum <= 3){
pFIO->FIOSET[byteNum] = bitValue;
}
}
}
/*********************************************************************//**
* @brief Clear bits for FIO port in byte accessible style
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] byteNum Byte part number, should be in range from 0 to 3
* @param[in] bitValue Value that contains all bits in to clear,
* in range from 0 to 0xFF.
* @return None
*
* Note:
* - For all bits that has been set as input direction, this function will
* not effect.
* - For all remaining bits that are not activated in bitValue (value '0')
* will not be effected by this function.
**********************************************************************/
void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)
{
GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
if (pFIO != NULL) {
if (byteNum <= 3){
pFIO->FIOCLR[byteNum] = bitValue;
}
}
}
/*********************************************************************//**
* @brief Read Current state on port pin that have input direction of GPIO
* in byte accessible style.
* @param[in] portNum Port number, in range from 0 to 4
* @param[in] byteNum Byte part number, should be in range from 0 to 3
* @return Current value of FIO port pin of specified byte part.
* Note: Return value contain state of each port pin (bit) on that FIO regardless
* its direction is input or output.
**********************************************************************/
uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum)
{
GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
if (pFIO != NULL) {
if (byteNum <= 3){
return (pFIO->FIOPIN[byteNum]);
}
}
return (0);
}
/**
* @}
*/
#endif /* _GPIO */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,663 @@
/**********************************************************************
* $Id$ lpc17xx_i2s.c 2010-09-23
*//**
* @file lpc17xx_i2s.c
* @brief Contains all functions support for I2S firmware
* library on LPC17xx
* @version 3.1
* @date 23. Sep. 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 I2S
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_i2s.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 _I2S
/* Private Functions ---------------------------------------------------------- */
static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode);
static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode);
/********************************************************************//**
* @brief Get I2S wordwidth value
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is the I2S mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return The wordwidth value, should be: 8,16 or 32
*********************************************************************/
static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
uint8_t value;
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) {
value = (I2Sx->I2SDAO) & 0x03; /* get wordwidth bit */
} else {
value = (I2Sx->I2SDAI) & 0x03; /* get wordwidth bit */
}
switch (value) {
case I2S_WORDWIDTH_8:
return 8;
case I2S_WORDWIDTH_16:
return 16;
default:
return 32;
}
}
/********************************************************************//**
* @brief Get I2S channel value
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is the I2S mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return The channel value, should be: 1(mono) or 2(stereo)
*********************************************************************/
static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
uint8_t value;
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) {
value = ((I2Sx->I2SDAO) & 0x04)>>2; /* get bit[2] */
} else {
value = ((I2Sx->I2SDAI) & 0x04)>>2; /* get bit[2] */
}
if(value == I2S_MONO) return 1;
return 2;
}
/* End of Private Functions --------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup I2S_Public_Functions
* @{
*/
/********************************************************************//**
* @brief Initialize I2S
* - Turn on power and clock
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @return none
*********************************************************************/
void I2S_Init(LPC_I2S_TypeDef *I2Sx) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
// Turn on power and clock
CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, ENABLE);
LPC_I2S->I2SDAI = LPC_I2S->I2SDAO = 0x00;
}
/********************************************************************//**
* @brief Configuration I2S, setting:
* - master/slave mode
* - wordwidth value
* - channel mode
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @param[in] ConfigStruct pointer to I2S_CFG_Type structure
* which will be initialized.
* @return none
*********************************************************************/
void I2S_Config(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct)
{
uint32_t bps, config;
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_WORDWIDTH(ConfigStruct->wordwidth));
CHECK_PARAM(PARAM_I2S_CHANNEL(ConfigStruct->mono));
CHECK_PARAM(PARAM_I2S_STOP(ConfigStruct->stop));
CHECK_PARAM(PARAM_I2S_RESET(ConfigStruct->reset));
CHECK_PARAM(PARAM_I2S_WS_SEL(ConfigStruct->ws_sel));
CHECK_PARAM(PARAM_I2S_MUTE(ConfigStruct->mute));
/* Setup clock */
bps = (ConfigStruct->wordwidth +1)*8;
/* Calculate audio config */
config = (bps - 1)<<6 | (ConfigStruct->ws_sel)<<5 | (ConfigStruct->reset)<<4 |
(ConfigStruct->stop)<<3 | (ConfigStruct->mono)<<2 | (ConfigStruct->wordwidth);
if(TRMode == I2S_RX_MODE){
LPC_I2S->I2SDAI = config;
}else{
LPC_I2S->I2SDAO = config;
}
}
/********************************************************************//**
* @brief DeInitial both I2S transmit or receive
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @return none
*********************************************************************/
void I2S_DeInit(LPC_I2S_TypeDef *I2Sx) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
// Turn off power and clock
CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, DISABLE);
}
/********************************************************************//**
* @brief Get I2S Buffer Level
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode Transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return current level of Transmit/Receive Buffer
*********************************************************************/
uint8_t I2S_GetLevel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if(TRMode == I2S_TX_MODE)
{
return ((I2Sx->I2SSTATE >> 16) & 0xFF);
}
else
{
return ((I2Sx->I2SSTATE >> 8) & 0xFF);
}
}
/********************************************************************//**
* @brief I2S Start: clear all STOP,RESET and MUTE bit, ready to operate
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @return none
*********************************************************************/
void I2S_Start(LPC_I2S_TypeDef *I2Sx)
{
//Clear STOP,RESET and MUTE bit
I2Sx->I2SDAO &= ~I2S_DAI_RESET;
I2Sx->I2SDAI &= ~I2S_DAI_RESET;
I2Sx->I2SDAO &= ~I2S_DAI_STOP;
I2Sx->I2SDAI &= ~I2S_DAI_STOP;
I2Sx->I2SDAO &= ~I2S_DAI_MUTE;
}
/********************************************************************//**
* @brief I2S Send data
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] BufferData pointer to uint32_t is the data will be send
* @return none
*********************************************************************/
void I2S_Send(LPC_I2S_TypeDef *I2Sx, uint32_t BufferData) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
I2Sx->I2STXFIFO = BufferData;
}
/********************************************************************//**
* @brief I2S Receive Data
* @param[in] I2Sx pointer to LPC_I2S_TypeDef
* @return received value
*********************************************************************/
uint32_t I2S_Receive(LPC_I2S_TypeDef* I2Sx) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
return (I2Sx->I2SRXFIFO);
}
/********************************************************************//**
* @brief I2S Pause
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_Pause(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) //Transmit mode
{
I2Sx->I2SDAO |= I2S_DAO_STOP;
} else //Receive mode
{
I2Sx->I2SDAI |= I2S_DAI_STOP;
}
}
/********************************************************************//**
* @brief I2S Mute
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_Mute(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) //Transmit mode
{
I2Sx->I2SDAO |= I2S_DAO_MUTE;
} else //Receive mode
{
I2Sx->I2SDAI |= I2S_DAI_MUTE;
}
}
/********************************************************************//**
* @brief I2S Stop
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_Stop(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) //Transmit mode
{
I2Sx->I2SDAO &= ~I2S_DAO_MUTE;
I2Sx->I2SDAO |= I2S_DAO_STOP;
I2Sx->I2SDAO |= I2S_DAO_RESET;
} else //Receive mode
{
I2Sx->I2SDAI |= I2S_DAI_STOP;
I2Sx->I2SDAI |= I2S_DAI_RESET;
}
}
/********************************************************************//**
* @brief Set frequency for I2S
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] Freq is the frequency for I2S will be set. It can range
* from 16-96 kHz(16, 22.05, 32, 44.1, 48, 96kHz)
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return Status: ERROR or SUCCESS
*********************************************************************/
Status I2S_FreqConfig(LPC_I2S_TypeDef *I2Sx, uint32_t Freq, uint8_t TRMode) {
uint32_t i2s_clk;
uint8_t channel, wordwidth;
uint32_t x, y;
uint64_t divider;
uint16_t dif;
uint16_t x_divide, y_divide;
uint16_t err, ErrorOptimal = 0xFFFF;
uint32_t N;
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PRAM_I2S_FREQ(Freq));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
//Get the frequency of PCLK_I2S
i2s_clk = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_I2S);
if(TRMode == I2S_TX_MODE)
{
channel = i2s_GetChannel(I2Sx,I2S_TX_MODE);
wordwidth = i2s_GetWordWidth(I2Sx,I2S_TX_MODE);
}
else
{
channel = i2s_GetChannel(I2Sx,I2S_RX_MODE);
wordwidth = i2s_GetWordWidth(I2Sx,I2S_RX_MODE);
}
/* Calculate X and Y divider
* The MCLK rate for the I2S transmitter is determined by the value
* in the I2STXRATE/I2SRXRATE register. The required I2STXRATE/I2SRXRATE
* setting depends on the desired audio sample rate desired, the format
* (stereo/mono) used, and the data size.
* The formula is:
* I2S_MCLK = PCLK_I2S * (X/Y) / 2
* In that, Y must be greater than or equal to X. X should divides evenly
* into Y.
* We have:
* I2S_MCLK = Freq * channel*wordwidth * (I2STXBITRATE+1);
* So: (X/Y) = (Freq * channel*wordwidth * (I2STXBITRATE+1))*2/PCLK_I2S
* We use a loop function to chose the most suitable X,Y value
*/
/* divider is a fixed point number with 16 fractional bits */
divider = (((uint64_t)Freq *channel*wordwidth * 2)<<16) / i2s_clk;
/* find N that make x/y <= 1 -> divider <= 2^16 */
for(N=64;N>0;N--){
if((divider*N) < (1<<16)) break;
}
if(N == 0) return ERROR;
divider *= N;
for (y = 255; y > 0; y--) {
x = y * divider;
if(x & (0xFF000000)) continue;
dif = x & 0xFFFF;
if(dif>0x8000) err = 0x10000-dif;
else err = dif;
if (err == 0)
{
y_divide = y;
break;
}
else if (err < ErrorOptimal)
{
ErrorOptimal = err;
y_divide = y;
}
}
x_divide = ((uint64_t)y_divide * Freq *(channel*wordwidth)* N * 2)/i2s_clk;
if(x_divide >= 256) x_divide = 0xFF;
if(x_divide == 0) x_divide = 1;
if (TRMode == I2S_TX_MODE)// Transmitter
{
I2Sx->I2STXBITRATE = N-1;
I2Sx->I2STXRATE = y_divide | (x_divide << 8);
} else //Receiver
{
I2Sx->I2SRXBITRATE = N-1;
I2Sx->I2STXRATE = y_divide | (x_divide << 8);
}
return SUCCESS;
}
/********************************************************************//**
* @brief I2S set bitrate
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] bitrate value will be set
* bitrate value should be in range: 0 .. 63
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_SetBitRate(LPC_I2S_TypeDef *I2Sx, uint8_t bitrate, uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_BITRATE(bitrate));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if(TRMode == I2S_TX_MODE)
{
I2Sx->I2STXBITRATE = bitrate;
}
else
{
I2Sx->I2SRXBITRATE = bitrate;
}
}
/********************************************************************//**
* @brief Configuration operating mode for I2S
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] ModeConfig pointer to I2S_MODEConf_Type will be used to
* configure
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_ModeConfig(LPC_I2S_TypeDef *I2Sx, I2S_MODEConf_Type* ModeConfig,
uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_CLKSEL(ModeConfig->clksel));
CHECK_PARAM(PARAM_I2S_4PIN(ModeConfig->fpin));
CHECK_PARAM(PARAM_I2S_MCLK(ModeConfig->mcena));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_TX_MODE) {
I2Sx->I2STXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
I2Sx->I2STXMODE |= 0x02;
}
if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
I2Sx->I2STXMODE |= (1 << 2);
}
if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
I2Sx->I2STXMODE |= (1 << 3);
}
} else {
I2Sx->I2SRXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
I2Sx->I2SRXMODE |= 0x02;
}
if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
I2Sx->I2SRXMODE |= (1 << 2);
}
if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
I2Sx->I2SRXMODE |= (1 << 3);
}
}
}
/********************************************************************//**
* @brief Configure DMA operation for I2S
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] DMAConfig pointer to I2S_DMAConf_Type will be used to configure
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return none
*********************************************************************/
void I2S_DMAConfig(LPC_I2S_TypeDef *I2Sx, I2S_DMAConf_Type* DMAConfig,
uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_DMA(DMAConfig->DMAIndex));
CHECK_PARAM(PARAM_I2S_DMA_DEPTH(DMAConfig->depth));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_RX_MODE) {
if (DMAConfig->DMAIndex == I2S_DMA_1) {
LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 8;
} else {
LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 8;
}
} else {
if (DMAConfig->DMAIndex == I2S_DMA_1) {
LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 16;
} else {
LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 16;
}
}
}
/********************************************************************//**
* @brief Enable/Disable DMA operation for I2S
* @param[in] I2Sx: I2S peripheral selected, should be: LPC_I2S
* @param[in] DMAIndex chose what DMA is used, should be:
* - I2S_DMA_1 = 0: DMA1
* - I2S_DMA_2 = 1: DMA2
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @param[in] NewState is new state of DMA operation, should be:
* - ENABLE
* - DISABLE
* @return none
*********************************************************************/
void I2S_DMACmd(LPC_I2S_TypeDef *I2Sx, uint8_t DMAIndex, uint8_t TRMode,
FunctionalState NewState)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
CHECK_PARAM(PARAM_I2S_DMA(DMAIndex));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
if (TRMode == I2S_RX_MODE) {
if (DMAIndex == I2S_DMA_1) {
if (NewState == ENABLE)
I2Sx->I2SDMA1 |= 0x01;
else
I2Sx->I2SDMA1 &= ~0x01;
} else {
if (NewState == ENABLE)
I2Sx->I2SDMA2 |= 0x01;
else
I2Sx->I2SDMA2 &= ~0x01;
}
} else {
if (DMAIndex == I2S_DMA_1) {
if (NewState == ENABLE)
I2Sx->I2SDMA1 |= 0x02;
else
I2Sx->I2SDMA1 &= ~0x02;
} else {
if (NewState == ENABLE)
I2Sx->I2SDMA2 |= 0x02;
else
I2Sx->I2SDMA2 &= ~0x02;
}
}
}
/********************************************************************//**
* @brief Configure IRQ for I2S
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @param[in] level is the FIFO level that triggers IRQ request
* @return none
*********************************************************************/
void I2S_IRQConfig(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, uint8_t level) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
CHECK_PARAM(PARAM_I2S_IRQ_LEVEL(level));
if (TRMode == I2S_RX_MODE) {
I2Sx->I2SIRQ |= (level << 8);
} else {
I2Sx->I2SIRQ |= (level << 16);
}
}
/********************************************************************//**
* @brief Enable/Disable IRQ for I2S
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @param[in] NewState is new state of DMA operation, should be:
* - ENABLE
* - DISABLE
* @return none
*********************************************************************/
void I2S_IRQCmd(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, FunctionalState NewState) {
CHECK_PARAM(PARAM_I2Sx(I2Sx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (TRMode == I2S_RX_MODE) {
if (NewState == ENABLE)
I2Sx->I2SIRQ |= 0x01;
else
I2Sx->I2SIRQ &= ~0x01;
//Enable DMA
} else {
if (NewState == ENABLE)
I2Sx->I2SIRQ |= 0x02;
else
I2Sx->I2SIRQ &= ~0x02;
}
}
/********************************************************************//**
* @brief Get I2S interrupt status
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return FunctionState should be:
* - ENABLE: interrupt is enable
* - DISABLE: interrupt is disable
*********************************************************************/
FunctionalState I2S_GetIRQStatus(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
if(TRMode == I2S_TX_MODE)
return ((FunctionalState)((I2Sx->I2SIRQ >> 1)&0x01));
else
return ((FunctionalState)((I2Sx->I2SIRQ)&0x01));
}
/********************************************************************//**
* @brief Get I2S interrupt depth
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
* @param[in] TRMode is transmit/receive mode, should be:
* - I2S_TX_MODE = 0: transmit mode
* - I2S_RX_MODE = 1: receive mode
* @return depth of FIFO level on which to create an irq request
*********************************************************************/
uint8_t I2S_GetIRQDepth(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode)
{
CHECK_PARAM(PARAM_I2Sx(I2Sx));
if(TRMode == I2S_TX_MODE)
return (((I2Sx->I2SIRQ)>>16)&0xFF);
else
return (((I2Sx->I2SIRQ)>>8)&0xFF);
}
/**
* @}
*/
#endif /* _I2S */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,308 @@
/**********************************************************************
* $Id$ lpc17xx_iap.c 2012-04-18
*//**
* @file lpc17xx_iap.c
* @brief Contains all functions support for IAP on lpc17xx
* @version 1.0
* @date 18. April. 2012
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, 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.
**********************************************************************/
#include "lpc17xx_iap.h"
#include "system_LPC17xx.h"
// IAP Command
typedef void (*IAP)(uint32_t *cmd,uint32_t *result);
IAP iap_entry = (IAP) IAP_LOCATION;
#define IAP_Call iap_entry
/** @addtogroup IAP_Public_Functions IAP Public Function
* @ingroup IAP
* @{
*/
/*********************************************************************//**
* @brief Get Sector Number
*
* @param[in] adr Sector Address
*
* @return Sector Number.
*
**********************************************************************/
uint32_t GetSecNum (uint32_t adr)
{
uint32_t n;
n = adr >> 12; // 4kB Sector
if (n >= 0x10) {
n = 0x0E + (n >> 3); // 32kB Sector
}
return (n); // Sector Number
}
/*********************************************************************//**
* @brief Prepare sector(s) for write operation
*
* @param[in] start_sec The number of start sector
* @param[in] end_sec The number of end sector
*
* @return CMD_SUCCESS/BUSY/INVALID_SECTOR.
*
**********************************************************************/
IAP_STATUS_CODE PrepareSector(uint32_t start_sec, uint32_t end_sec)
{
IAP_COMMAND_Type command;
command.cmd = IAP_PREPARE; // Prepare Sector for Write
command.param[0] = start_sec; // Start Sector
command.param[1] = end_sec; // End Sector
IAP_Call (&command.cmd, &command.status); // Call IAP Command
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Copy RAM to Flash
*
* @param[in] dest destination buffer (in Flash memory).
* @param[in] source source buffer (in RAM).
* @param[in] size the write size.
*
* @return CMD_SUCCESS.
* SRC_ADDR_ERROR/DST_ADDR_ERROR
* SRC_ADDR_NOT_MAPPED/DST_ADDR_NOT_MAPPED
* COUNT_ERROR/SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION
* BUSY
*
**********************************************************************/
IAP_STATUS_CODE CopyRAM2Flash(uint8_t * dest, uint8_t* source, IAP_WRITE_SIZE size)
{
uint32_t sec;
IAP_STATUS_CODE status;
IAP_COMMAND_Type command;
// Prepare sectors
sec = GetSecNum((uint32_t)dest);
status = PrepareSector(sec, sec);
if(status != CMD_SUCCESS)
return status;
// write
command.cmd = IAP_COPY_RAM2FLASH; // Copy RAM to Flash
command.param[0] = (uint32_t)dest; // Destination Flash Address
command.param[1] = (uint32_t)source; // Source RAM Address
command.param[2] = size; // Number of bytes
command.param[3] = SystemCoreClock / 1000; // CCLK in kHz
IAP_Call (&command.cmd, &command.status); // Call IAP Command
return (IAP_STATUS_CODE)command.status; // Finished without Errors
}
/*********************************************************************//**
* @brief Erase sector(s)
*
* @param[in] start_sec The number of start sector
* @param[in] end_sec The number of end sector
*
* @return CMD_SUCCESS.
* INVALID_SECTOR
* SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION
* BUSY
*
**********************************************************************/
IAP_STATUS_CODE EraseSector(uint32_t start_sec, uint32_t end_sec)
{
IAP_COMMAND_Type command;
IAP_STATUS_CODE status;
// Prepare sectors
status = PrepareSector(start_sec, end_sec);
if(status != CMD_SUCCESS)
return status;
// Erase sectors
command.cmd = IAP_ERASE; // Prepare Sector for Write
command.param[0] = start_sec; // Start Sector
command.param[1] = end_sec; // End Sector
command.param[2] = SystemCoreClock / 1000; // CCLK in kHz
IAP_Call (&command.cmd, &command.status); // Call IAP Command
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Blank check sector(s)
*
* @param[in] start_sec The number of start sector
* @param[in] end_sec The number of end sector
* @param[out] first_nblank_loc The offset of the first non-blank word
* @param[out] first_nblank_val The value of the first non-blank word
*
* @return CMD_SUCCESS.
* INVALID_SECTOR
* SECTOR_NOT_BLANK
* BUSY
*
**********************************************************************/
IAP_STATUS_CODE BlankCheckSector(uint32_t start_sec, uint32_t end_sec,
uint32_t *first_nblank_loc,
uint32_t *first_nblank_val)
{
IAP_COMMAND_Type command;
command.cmd = IAP_BLANK_CHECK; // Prepare Sector for Write
command.param[0] = start_sec; // Start Sector
command.param[1] = end_sec; // End Sector
IAP_Call (&command.cmd, &command.status); // Call IAP Command
if(command.status == SECTOR_NOT_BLANK)
{
// Update out value
if(first_nblank_loc != NULL)
*first_nblank_loc = command.result[0];
if(first_nblank_val != NULL)
*first_nblank_val = command.result[1];
}
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Read part identification number
*
* @param[out] partID Part ID
*
* @return CMD_SUCCESS
*
**********************************************************************/
IAP_STATUS_CODE ReadPartID(uint32_t *partID)
{
IAP_COMMAND_Type command;
command.cmd = IAP_READ_PART_ID;
IAP_Call (&command.cmd, &command.status); // Call IAP Command
if(command.status == CMD_SUCCESS)
{
if(partID != NULL)
*partID = command.result[0];
}
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Read boot code version. The version is interpreted as <major>.<minor>.
*
* @param[out] major The major
* @param[out] minor The minor
*
* @return CMD_SUCCESS
*
**********************************************************************/
IAP_STATUS_CODE ReadBootCodeVer(uint8_t *major, uint8_t* minor)
{
IAP_COMMAND_Type command;
command.cmd = IAP_READ_BOOT_VER;
IAP_Call (&command.cmd, &command.status); // Call IAP Command
if(command.status == CMD_SUCCESS)
{
if(major != NULL)
*major = (command.result[0] >> 8) & 0xFF;
if(minor != NULL)
*minor = (command.result[0]) & 0xFF;
}
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Read Device serial number.
*
* @param[out] uid Serial number.
*
* @return CMD_SUCCESS
*
**********************************************************************/
IAP_STATUS_CODE ReadDeviceSerialNum(uint32_t *uid)
{
IAP_COMMAND_Type command;
command.cmd = IAP_READ_SERIAL_NUMBER;
IAP_Call (&command.cmd, &command.status); // Call IAP Command
if(command.status == CMD_SUCCESS)
{
if(uid != NULL)
{
uint32_t i = 0;
for(i = 0; i < 4; i++)
uid[i] = command.result[i];
}
}
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief compare the memory contents at two locations.
*
* @param[in] addr1 The address of the 1st buffer (in RAM/Flash).
* @param[in] addr2 The address of the 2nd buffer (in RAM/Flash).
* @param[in] size Number of bytes to be compared; should be a multiple of 4.
*
* @return CMD_SUCCESS
* COMPARE_ERROR
* COUNT_ERROR (Byte count is not a multiple of 4)
* ADDR_ERROR
* ADDR_NOT_MAPPED
*
**********************************************************************/
IAP_STATUS_CODE Compare(uint8_t *addr1, uint8_t *addr2, uint32_t size)
{
IAP_COMMAND_Type command;
command.cmd = IAP_COMPARE;
command.param[0] = (uint32_t)addr1;
command.param[1] = (uint32_t)addr2;
command.param[2] = size;
IAP_Call (&command.cmd, &command.status); // Call IAP Command
return (IAP_STATUS_CODE)command.status;
}
/*********************************************************************//**
* @brief Re-invoke ISP.
*
* @param[in] None.
*
* @return None.
*
**********************************************************************/
void InvokeISP(void)
{
IAP_COMMAND_Type command;
command.cmd = IAP_REINVOKE_ISP;
IAP_Call (&command.cmd, &command.status); // Call IAP Command
}
/**
* @}
*/

View File

@ -0,0 +1,76 @@
/**********************************************************************
* $Id$ lpc17xx_libcfg_default.c 2010-05-21
*//**
* @file lpc17xx_libcfg_default.c
* @brief Library configuration source file (default), used to build
* library without examples
* @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.
**********************************************************************/
/* Library group ----------------------------------------------------------- */
/** @addtogroup LIBCFG_DEFAULT
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_libcfg_default.h"
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup LIBCFG_DEFAULT_Public_Functions
* @{
*/
#ifndef __BUILD_WITH_EXAMPLE__
#ifdef DEBUG
/*******************************************************************************
* @brief Reports the name of the source file and the source line number
* where the CHECK_PARAM error has occurred.
* @param[in] file Pointer to the source file name
* @param[in] line assert_param error line source number
* @return None
*******************************************************************************/
void check_failed(uint8_t *file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while(1);
}
#endif /* DEBUG */
#endif /* __BUILD_WITH_EXAMPLE__ */
/**
* @}
*/
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,509 @@
/**********************************************************************
* $Id$ lpc17xx_mcpwm.c 2010-05-21
*//**
* @file lpc17xx_mcpwm.c
* @brief Contains all functions support for Motor Control PWM 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 MCPWM
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_mcpwm.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 _MCPWM
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup MCPWM_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initializes the MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected,
* Should be: LPC_MCPWM
* @return None
**********************************************************************/
void MCPWM_Init(LPC_MCPWM_TypeDef *MCPWMx)
{
/* Turn On MCPWM PCLK */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCMC, ENABLE);
/* As default, peripheral clock for MCPWM module
* is set to FCCLK / 2 */
// CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_MC, CLKPWR_PCLKSEL_CCLK_DIV_2);
MCPWMx->MCCAP_CLR = MCPWM_CAPCLR_CAP(0) | MCPWM_CAPCLR_CAP(1) | MCPWM_CAPCLR_CAP(2);
MCPWMx->MCINTFLAG_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \
| MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \
| MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2);
MCPWMx->MCINTEN_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \
| MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \
| MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2);
}
/*********************************************************************//**
* @brief Configures each channel in MCPWM peripheral according to the
* specified parameters in the MCPWM_CHANNEL_CFG_Type.
* @param[in] MCPWMx Motor Control PWM peripheral selected
* should be: LPC_MCPWM
* @param[in] channelNum Channel number, should be: 0..2.
* @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure
* that contains the configuration information for the
* specified MCPWM channel.
* @return None
**********************************************************************/
void MCPWM_ConfigChannel(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum,
MCPWM_CHANNEL_CFG_Type * channelSetup)
{
if (channelNum <= 2) {
if (channelNum == 0) {
MCPWMx->MCTIM0 = channelSetup->channelTimercounterValue;
MCPWMx->MCPER0 = channelSetup->channelPeriodValue;
MCPWMx->MCPW0 = channelSetup->channelPulsewidthValue;
} else if (channelNum == 1) {
MCPWMx->MCTIM1 = channelSetup->channelTimercounterValue;
MCPWMx->MCPER1 = channelSetup->channelPeriodValue;
MCPWMx->MCPW1 = channelSetup->channelPulsewidthValue;
} else if (channelNum == 2) {
MCPWMx->MCTIM2 = channelSetup->channelTimercounterValue;
MCPWMx->MCPER2 = channelSetup->channelPeriodValue;
MCPWMx->MCPW2 = channelSetup->channelPulsewidthValue;
} else {
return;
}
if (channelSetup->channelType /* == MCPWM_CHANNEL_CENTER_MODE */){
MCPWMx->MCCON_SET = MCPWM_CON_CENTER(channelNum);
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_CENTER(channelNum);
}
if (channelSetup->channelPolarity /* == MCPWM_CHANNEL_PASSIVE_HI */){
MCPWMx->MCCON_SET = MCPWM_CON_POLAR(channelNum);
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_POLAR(channelNum);
}
if (channelSetup->channelDeadtimeEnable /* == ENABLE */){
MCPWMx->MCCON_SET = MCPWM_CON_DTE(channelNum);
MCPWMx->MCDEADTIME &= ~(MCPWM_DT(channelNum, 0x3FF));
MCPWMx->MCDEADTIME |= MCPWM_DT(channelNum, channelSetup->channelDeadtimeValue);
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_DTE(channelNum);
}
if (channelSetup->channelUpdateEnable /* == ENABLE */){
MCPWMx->MCCON_CLR = MCPWM_CON_DISUP(channelNum);
} else {
MCPWMx->MCCON_SET = MCPWM_CON_DISUP(channelNum);
}
}
}
/*********************************************************************//**
* @brief Write to MCPWM shadow registers - Update the value for period
* and pulse width in MCPWM peripheral.
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] channelNum Channel Number, should be: 0..2.
* @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure
* that contains the configuration information for the
* specified MCPWM channel.
* @return None
**********************************************************************/
void MCPWM_WriteToShadow(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum,
MCPWM_CHANNEL_CFG_Type *channelSetup)
{
if (channelNum == 0){
MCPWMx->MCPER0 = channelSetup->channelPeriodValue;
MCPWMx->MCPW0 = channelSetup->channelPulsewidthValue;
} else if (channelNum == 1) {
MCPWMx->MCPER1 = channelSetup->channelPeriodValue;
MCPWMx->MCPW1 = channelSetup->channelPulsewidthValue;
} else if (channelNum == 2) {
MCPWMx->MCPER2 = channelSetup->channelPeriodValue;
MCPWMx->MCPW2 = channelSetup->channelPulsewidthValue;
}
}
/*********************************************************************//**
* @brief Configures capture function in MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] channelNum MCI (Motor Control Input pin) number
* Should be: 0..2
* @param[in] captureConfig Pointer to a MCPWM_CAPTURE_CFG_Type structure
* that contains the configuration information for the
* specified MCPWM capture.
* @return
**********************************************************************/
void MCPWM_ConfigCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum,
MCPWM_CAPTURE_CFG_Type *captureConfig)
{
if (channelNum <= 2) {
if (captureConfig->captureFalling /* == ENABLE */) {
MCPWMx->MCCAPCON_SET = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum);
} else {
MCPWMx->MCCAPCON_CLR = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum);
}
if (captureConfig->captureRising /* == ENABLE */) {
MCPWMx->MCCAPCON_SET = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum);
} else {
MCPWMx->MCCAPCON_CLR = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum);
}
if (captureConfig->timerReset /* == ENABLE */){
MCPWMx->MCCAPCON_SET = MCPWM_CAPCON_RT(captureConfig->captureChannel);
} else {
MCPWMx->MCCAPCON_CLR = MCPWM_CAPCON_RT(captureConfig->captureChannel);
}
if (captureConfig->hnfEnable /* == ENABLE */){
MCPWMx->MCCAPCON_SET = MCPWM_CAPCON_HNFCAP(channelNum);
} else {
MCPWMx->MCCAPCON_CLR = MCPWM_CAPCON_HNFCAP(channelNum);
}
}
}
/*********************************************************************//**
* @brief Clears current captured value in specified capture channel
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] captureChannel Capture channel number, should be: 0..2
* @return None
**********************************************************************/
void MCPWM_ClearCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel)
{
MCPWMx->MCCAP_CLR = MCPWM_CAPCLR_CAP(captureChannel);
}
/*********************************************************************//**
* @brief Get current captured value in specified capture channel
* @param[in] MCPWMx Motor Control PWM peripheral selected,
* Should be: LPC_MCPWM
* @param[in] captureChannel Capture channel number, should be: 0..2
* @return None
**********************************************************************/
uint32_t MCPWM_GetCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel)
{
if (captureChannel == 0){
return (MCPWMx->MCCR0);
} else if (captureChannel == 1) {
return (MCPWMx->MCCR1);
} else if (captureChannel == 2) {
return (MCPWMx->MCCR2);
}
return (0);
}
/*********************************************************************//**
* @brief Configures Count control in MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] channelNum Channel number, should be: 0..2
* @param[in] countMode Count mode, should be:
* - ENABLE: Enables count mode.
* - DISABLE: Disable count mode, the channel is in timer mode.
* @param[in] countConfig Pointer to a MCPWM_COUNT_CFG_Type structure
* that contains the configuration information for the
* specified MCPWM count control.
* @return None
**********************************************************************/
void MCPWM_CountConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum,
uint32_t countMode, MCPWM_COUNT_CFG_Type *countConfig)
{
if (channelNum <= 2) {
if (countMode /* == ENABLE */){
MCPWMx->MCCNTCON_SET = MCPWM_CNTCON_CNTR(channelNum);
if (countConfig->countFalling /* == ENABLE */) {
MCPWMx->MCCNTCON_SET = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum);
} else {
MCPWMx->MCCNTCON_CLR = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum);
}
if (countConfig->countRising /* == ENABLE */) {
MCPWMx->MCCNTCON_SET = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum);
} else {
MCPWMx->MCCNTCON_CLR = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum);
}
} else {
MCPWMx->MCCNTCON_CLR = MCPWM_CNTCON_CNTR(channelNum);
}
}
}
/*********************************************************************//**
* @brief Start MCPWM activity for each MCPWM channel
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] channel0 State of this command on channel 0:
* - ENABLE: 'Start' command will effect on channel 0
* - DISABLE: 'Start' command will not effect on channel 0
* @param[in] channel1 State of this command on channel 1:
* - ENABLE: 'Start' command will effect on channel 1
* - DISABLE: 'Start' command will not effect on channel 1
* @param[in] channel2 State of this command on channel 2:
* - ENABLE: 'Start' command will effect on channel 2
* - DISABLE: 'Start' command will not effect on channel 2
* @return None
**********************************************************************/
void MCPWM_Start(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channel0,
uint32_t channel1, uint32_t channel2)
{
uint32_t regVal = 0;
regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \
| (channel2 ? MCPWM_CON_RUN(2) : 0);
MCPWMx->MCCON_SET = regVal;
}
/*********************************************************************//**
* @brief Stop MCPWM activity for each MCPWM channel
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] channel0 State of this command on channel 0:
* - ENABLE: 'Stop' command will effect on channel 0
* - DISABLE: 'Stop' command will not effect on channel 0
* @param[in] channel1 State of this command on channel 1:
* - ENABLE: 'Stop' command will effect on channel 1
* - DISABLE: 'Stop' command will not effect on channel 1
* @param[in] channel2 State of this command on channel 2:
* - ENABLE: 'Stop' command will effect on channel 2
* - DISABLE: 'Stop' command will not effect on channel 2
* @return None
**********************************************************************/
void MCPWM_Stop(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channel0,
uint32_t channel1, uint32_t channel2)
{
uint32_t regVal = 0;
regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \
| (channel2 ? MCPWM_CON_RUN(2) : 0);
MCPWMx->MCCON_CLR = regVal;
}
/*********************************************************************//**
* @brief Enables/Disables 3-phase AC motor mode on MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] acMode State of this command, should be:
* - ENABLE.
* - DISABLE.
* @return None
**********************************************************************/
void MCPWM_ACMode(LPC_MCPWM_TypeDef *MCPWMx, uint32_t acMode)
{
if (acMode){
MCPWMx->MCCON_SET = MCPWM_CON_ACMODE;
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_ACMODE;
}
}
/*********************************************************************//**
* @brief Enables/Disables 3-phase DC motor mode on MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] dcMode State of this command, should be:
* - ENABLE.
* - DISABLE.
* @param[in] outputInvered Polarity of the MCOB outputs for all 3 channels,
* should be:
* - ENABLE: The MCOB outputs have opposite polarity
* from the MCOA outputs.
* - DISABLE: The MCOB outputs have the same basic
* polarity as the MCOA outputs.
* @param[in] outputPattern A value contains bits that enables/disables the specified
* output pins route to the internal MCOA0 signal, should be:
- MCPWM_PATENT_A0: MCOA0 tracks internal MCOA0
- MCPWM_PATENT_B0: MCOB0 tracks internal MCOA0
- MCPWM_PATENT_A1: MCOA1 tracks internal MCOA0
- MCPWM_PATENT_B1: MCOB1 tracks internal MCOA0
- MCPWM_PATENT_A2: MCOA2 tracks internal MCOA0
- MCPWM_PATENT_B2: MCOB2 tracks internal MCOA0
* @return None
*
* Note: all these outputPatent values above can be ORed together for using as input parameter.
**********************************************************************/
void MCPWM_DCMode(LPC_MCPWM_TypeDef *MCPWMx, uint32_t dcMode,
uint32_t outputInvered, uint32_t outputPattern)
{
if (dcMode){
MCPWMx->MCCON_SET = MCPWM_CON_DCMODE;
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_DCMODE;
}
if (outputInvered) {
MCPWMx->MCCON_SET = MCPWM_CON_INVBDC;
} else {
MCPWMx->MCCON_CLR = MCPWM_CON_INVBDC;
}
MCPWMx->MCCCP = outputPattern;
}
/*********************************************************************//**
* @brief Configures the specified interrupt in MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be: LPC_MCPWM
* @param[in] ulIntType Interrupt type, should be:
* - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0)
* - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0)
* - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0)
* - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1)
* - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1)
* - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1)
* - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2)
* - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2)
* - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2)
* - MCPWM_INTFLAG_ABORT: Fast abort interrupt
* @param[in] NewState New State of this command, should be:
* - ENABLE.
* - DISABLE.
* @return None
*
* Note: all these ulIntType values above can be ORed together for using as input parameter.
**********************************************************************/
void MCPWM_IntConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType, FunctionalState NewState)
{
if (NewState) {
MCPWMx->MCINTEN_SET = ulIntType;
} else {
MCPWMx->MCINTEN_CLR = ulIntType;
}
}
/*********************************************************************//**
* @brief Sets/Forces the specified interrupt for MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected
* Should be LPC_MCPWM
* @param[in] ulIntType Interrupt type, should be:
* - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0)
* - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0)
* - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0)
* - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1)
* - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1)
* - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1)
* - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2)
* - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2)
* - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2)
* - MCPWM_INTFLAG_ABORT: Fast abort interrupt
* @return None
* Note: all these ulIntType values above can be ORed together for using as input parameter.
**********************************************************************/
void MCPWM_IntSet(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType)
{
MCPWMx->MCINTFLAG_SET = ulIntType;
}
/*********************************************************************//**
* @brief Clear the specified interrupt pending for MCPWM peripheral
* @param[in] MCPWMx Motor Control PWM peripheral selected,
* should be: LPC_MCPWM
* @param[in] ulIntType Interrupt type, should be:
* - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0)
* - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0)
* - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0)
* - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1)
* - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1)
* - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1)
* - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2)
* - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2)
* - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2)
* - MCPWM_INTFLAG_ABORT: Fast abort interrupt
* @return None
* Note: all these ulIntType values above can be ORed together for using as input parameter.
**********************************************************************/
void MCPWM_IntClear(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType)
{
MCPWMx->MCINTFLAG_CLR = ulIntType;
}
/*********************************************************************//**
* @brief Check whether if the specified interrupt in MCPWM is set or not
* @param[in] MCPWMx Motor Control PWM peripheral selected,
* should be: LPC_MCPWM
* @param[in] ulIntType Interrupt type, should be:
* - MCPWM_INTFLAG_LIM0: Limit interrupt for channel (0)
* - MCPWM_INTFLAG_MAT0: Match interrupt for channel (0)
* - MCPWM_INTFLAG_CAP0: Capture interrupt for channel (0)
* - MCPWM_INTFLAG_LIM1: Limit interrupt for channel (1)
* - MCPWM_INTFLAG_MAT1: Match interrupt for channel (1)
* - MCPWM_INTFLAG_CAP1: Capture interrupt for channel (1)
* - MCPWM_INTFLAG_LIM2: Limit interrupt for channel (2)
* - MCPWM_INTFLAG_MAT2: Match interrupt for channel (2)
* - MCPWM_INTFLAG_CAP2: Capture interrupt for channel (2)
* - MCPWM_INTFLAG_ABORT: Fast abort interrupt
* @return None
**********************************************************************/
FlagStatus MCPWM_GetIntStatus(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType)
{
return ((MCPWMx->MCINTFLAG & ulIntType) ? SET : RESET);
}
/**
* @}
*/
#endif /* _MCPWM */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,148 @@
/**********************************************************************
* $Id$ lpc17xx_nvic.c 2010-05-21
*//**
* @file lpc17xx_nvic.c
* @brief Contains all expansion functions support for
* NVIC firmware library on LPC17xx. The main
* NVIC functions are defined in core_cm3.h
* @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 NVIC
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_nvic.h"
/* Private Macros ------------------------------------------------------------- */
/** @addtogroup NVIC_Private_Macros
* @{
*/
/* Vector table offset bit mask */
#define NVIC_VTOR_MASK 0x3FFFFF80
/**
* @}
*/
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup NVIC_Public_Functions
* @{
*/
/*****************************************************************************//**
* @brief De-initializes the NVIC peripheral registers to their default
* reset values.
* @param None
* @return None
*
* These following NVIC peripheral registers will be de-initialized:
* - Disable Interrupt (32 IRQ interrupt sources that matched with LPC17xx)
* - Clear all Pending Interrupts (32 IRQ interrupt source that matched with LPC17xx)
* - Clear all Interrupt Priorities (32 IRQ interrupt source that matched with LPC17xx)
*******************************************************************************/
void NVIC_DeInit(void)
{
uint8_t tmp;
/* Disable all interrupts */
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0x00000001;
/* Clear all pending interrupts */
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0x00000001;
/* Clear all interrupt priority */
for (tmp = 0; tmp < 32; tmp++) {
NVIC->IP[tmp] = 0x00;
}
}
/*****************************************************************************//**
* @brief De-initializes the SCB peripheral registers to their default
* reset values.
* @param none
* @return none
*
* These following SCB NVIC peripheral registers will be de-initialized:
* - Interrupt Control State register
* - Interrupt Vector Table Offset register
* - Application Interrupt/Reset Control register
* - System Control register
* - Configuration Control register
* - System Handlers Priority Registers
* - System Handler Control and State Register
* - Configurable Fault Status Register
* - Hard Fault Status Register
* - Debug Fault Status Register
*******************************************************************************/
void NVIC_SCBDeInit(void)
{
uint8_t tmp;
SCB->ICSR = 0x0A000000;
SCB->VTOR = 0x00000000;
SCB->AIRCR = 0x05FA0000;
SCB->SCR = 0x00000000;
SCB->CCR = 0x00000000;
for (tmp = 0; tmp < 32; tmp++) {
SCB->SHP[tmp] = 0x00;
}
SCB->SHCSR = 0x00000000;
SCB->CFSR = 0xFFFFFFFF;
SCB->HFSR = 0xFFFFFFFF;
SCB->DFSR = 0xFFFFFFFF;
}
/*****************************************************************************//**
* @brief Set Vector Table Offset value
* @param offset Offset value
* @return None
*******************************************************************************/
void NVIC_SetVTOR(uint32_t offset)
{
// SCB->VTOR = (offset & NVIC_VTOR_MASK);
SCB->VTOR = offset;
}
/**
* @}
*/
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,318 @@
/**********************************************************************
* $Id$ lpc17xx_pinsel.c 2010-05-21
*//**
* @file lpc17xx_pinsel.c
* @brief Contains all functions support for Pin connect block 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 PINSEL
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_pinsel.h"
/* Public Functions ----------------------------------------------------------- */
static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum);
static void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
static void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
/*********************************************************************//**
* @brief Setup the pin selection function
* @param[in] portnum PORT number,
* should be one of the following:
* - PINSEL_PORT_0 : Port 0
* - PINSEL_PORT_1 : Port 1
* - PINSEL_PORT_2 : Port 2
* - PINSEL_PORT_3 : Port 3
*
* @param[in] pinnum Pin number,
* should be one of the following:
- PINSEL_PIN_0 : Pin 0
- PINSEL_PIN_1 : Pin 1
- PINSEL_PIN_2 : Pin 2
- PINSEL_PIN_3 : Pin 3
- PINSEL_PIN_4 : Pin 4
- PINSEL_PIN_5 : Pin 5
- PINSEL_PIN_6 : Pin 6
- PINSEL_PIN_7 : Pin 7
- PINSEL_PIN_8 : Pin 8
- PINSEL_PIN_9 : Pin 9
- PINSEL_PIN_10 : Pin 10
- PINSEL_PIN_11 : Pin 11
- PINSEL_PIN_12 : Pin 12
- PINSEL_PIN_13 : Pin 13
- PINSEL_PIN_14 : Pin 14
- PINSEL_PIN_15 : Pin 15
- PINSEL_PIN_16 : Pin 16
- PINSEL_PIN_17 : Pin 17
- PINSEL_PIN_18 : Pin 18
- PINSEL_PIN_19 : Pin 19
- PINSEL_PIN_20 : Pin 20
- PINSEL_PIN_21 : Pin 21
- PINSEL_PIN_22 : Pin 22
- PINSEL_PIN_23 : Pin 23
- PINSEL_PIN_24 : Pin 24
- PINSEL_PIN_25 : Pin 25
- PINSEL_PIN_26 : Pin 26
- PINSEL_PIN_27 : Pin 27
- PINSEL_PIN_28 : Pin 28
- PINSEL_PIN_29 : Pin 29
- PINSEL_PIN_30 : Pin 30
- PINSEL_PIN_31 : Pin 31
* @param[in] funcnum Function number,
* should be one of the following:
* - PINSEL_FUNC_0 : default function
* - PINSEL_FUNC_1 : first alternate function
* - PINSEL_FUNC_2 : second alternate function
* - PINSEL_FUNC_3 : third alternate function
*
* @return None
**********************************************************************/
static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum)
{
uint32_t pinnum_t = pinnum;
uint32_t pinselreg_idx = 2 * portnum;
uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0;
if (pinnum_t >= 16) {
pinnum_t -= 16;
pinselreg_idx++;
}
*(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2));
*(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2);
}
/*********************************************************************//**
* @brief Setup resistor mode for each pin
* @param[in] portnum PORT number,
* should be one of the following:
* - PINSEL_PORT_0 : Port 0
* - PINSEL_PORT_1 : Port 1
* - PINSEL_PORT_2 : Port 2
* - PINSEL_PORT_3 : Port 3
* @param[in] pinnum Pin number,
* should be one of the following:
- PINSEL_PIN_0 : Pin 0
- PINSEL_PIN_1 : Pin 1
- PINSEL_PIN_2 : Pin 2
- PINSEL_PIN_3 : Pin 3
- PINSEL_PIN_4 : Pin 4
- PINSEL_PIN_5 : Pin 5
- PINSEL_PIN_6 : Pin 6
- PINSEL_PIN_7 : Pin 7
- PINSEL_PIN_8 : Pin 8
- PINSEL_PIN_9 : Pin 9
- PINSEL_PIN_10 : Pin 10
- PINSEL_PIN_11 : Pin 11
- PINSEL_PIN_12 : Pin 12
- PINSEL_PIN_13 : Pin 13
- PINSEL_PIN_14 : Pin 14
- PINSEL_PIN_15 : Pin 15
- PINSEL_PIN_16 : Pin 16
- PINSEL_PIN_17 : Pin 17
- PINSEL_PIN_18 : Pin 18
- PINSEL_PIN_19 : Pin 19
- PINSEL_PIN_20 : Pin 20
- PINSEL_PIN_21 : Pin 21
- PINSEL_PIN_22 : Pin 22
- PINSEL_PIN_23 : Pin 23
- PINSEL_PIN_24 : Pin 24
- PINSEL_PIN_25 : Pin 25
- PINSEL_PIN_26 : Pin 26
- PINSEL_PIN_27 : Pin 27
- PINSEL_PIN_28 : Pin 28
- PINSEL_PIN_29 : Pin 29
- PINSEL_PIN_30 : Pin 30
- PINSEL_PIN_31 : Pin 31
* @param[in] modenum: Mode number,
* should be one of the following:
- PINSEL_PINMODE_PULLUP : Internal pull-up resistor
- PINSEL_PINMODE_TRISTATE : Tri-state
- PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor
* @return None
**********************************************************************/
void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
{
uint32_t pinnum_t = pinnum;
uint32_t pinmodereg_idx = 2 * portnum;
uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0;
if (pinnum_t >= 16) {
pinnum_t -= 16;
pinmodereg_idx++ ;
}
*(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2));
*(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2);
}
/*********************************************************************//**
* @brief Setup Open drain mode for each pin
* @param[in] portnum PORT number,
* should be one of the following:
* - PINSEL_PORT_0 : Port 0
* - PINSEL_PORT_1 : Port 1
* - PINSEL_PORT_2 : Port 2
* - PINSEL_PORT_3 : Port 3
*
* @param[in] pinnum Pin number,
* should be one of the following:
- PINSEL_PIN_0 : Pin 0
- PINSEL_PIN_1 : Pin 1
- PINSEL_PIN_2 : Pin 2
- PINSEL_PIN_3 : Pin 3
- PINSEL_PIN_4 : Pin 4
- PINSEL_PIN_5 : Pin 5
- PINSEL_PIN_6 : Pin 6
- PINSEL_PIN_7 : Pin 7
- PINSEL_PIN_8 : Pin 8
- PINSEL_PIN_9 : Pin 9
- PINSEL_PIN_10 : Pin 10
- PINSEL_PIN_11 : Pin 11
- PINSEL_PIN_12 : Pin 12
- PINSEL_PIN_13 : Pin 13
- PINSEL_PIN_14 : Pin 14
- PINSEL_PIN_15 : Pin 15
- PINSEL_PIN_16 : Pin 16
- PINSEL_PIN_17 : Pin 17
- PINSEL_PIN_18 : Pin 18
- PINSEL_PIN_19 : Pin 19
- PINSEL_PIN_20 : Pin 20
- PINSEL_PIN_21 : Pin 21
- PINSEL_PIN_22 : Pin 22
- PINSEL_PIN_23 : Pin 23
- PINSEL_PIN_24 : Pin 24
- PINSEL_PIN_25 : Pin 25
- PINSEL_PIN_26 : Pin 26
- PINSEL_PIN_27 : Pin 27
- PINSEL_PIN_28 : Pin 28
- PINSEL_PIN_29 : Pin 29
- PINSEL_PIN_30 : Pin 30
- PINSEL_PIN_31 : Pin 31
* @param[in] modenum Open drain mode number,
* should be one of the following:
* - PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode
* - PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode
*
* @return None
**********************************************************************/
void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
{
uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0;
if (modenum == PINSEL_PINMODE_OPENDRAIN){
*(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum);
} else {
*(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum);
}
}
/* End of Public Functions ---------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup PINSEL_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Configure trace function
* @param[in] NewState State of the Trace function configuration,
* should be one of the following:
* - ENABLE : Enable Trace Function
* - DISABLE : Disable Trace Function
*
* @return None
**********************************************************************/
void PINSEL_ConfigTraceFunc(FunctionalState NewState)
{
if (NewState == ENABLE) {
LPC_PINCON->PINSEL10 |= (0x01UL << 3);
} else if (NewState == DISABLE) {
LPC_PINCON->PINSEL10 &= ~(0x01UL << 3);
}
}
/*********************************************************************//**
* @brief Setup I2C0 pins
* @param[in] i2cPinMode I2C pin mode,
* should be one of the following:
* - PINSEL_I2C_Normal_Mode : The standard drive mode
* - PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode
*
* @param[in] filterSlewRateEnable should be:
* - ENABLE: Enable filter and slew rate.
* - DISABLE: Disable filter and slew rate.
*
* @return None
**********************************************************************/
void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable)
{
uint32_t regVal;
if (i2cPinMode == PINSEL_I2C_Fast_Mode){
regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0;
}
if (filterSlewRateEnable == DISABLE){
regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0;
}
LPC_PINCON->I2CPADCFG = regVal;
}
/*********************************************************************//**
* @brief Configure Pin corresponding to specified parameters passed
* in the PinCfg
* @param[in] PinCfg Pointer to a PINSEL_CFG_Type structure
* that contains the configuration information for the
* specified pin.
* @return None
**********************************************************************/
void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg)
{
set_PinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum);
set_ResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode);
set_OpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain);
}
/**
* @}
*/
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,588 @@
/**********************************************************************
* $Id$ lpc17xx_pwm.c 2011-03-31
*//**
* @file lpc17xx_pwm.c
* @brief Contains all functions support for PWM firmware library on LPC17xx
* @version 2.1
* @date 31. Mar. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, 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 PWM
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_pwm.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 _PWM
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup PWM_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Check whether specified interrupt flag in PWM is set or not
* @param[in] PWMx: PWM peripheral, should be LPC_PWM1
* @param[in] IntFlag: PWM interrupt flag, should be:
* - PWM_INTSTAT_MR0: Interrupt flag for PWM match channel 0
* - PWM_INTSTAT_MR1: Interrupt flag for PWM match channel 1
* - PWM_INTSTAT_MR2: Interrupt flag for PWM match channel 2
* - PWM_INTSTAT_MR3: Interrupt flag for PWM match channel 3
* - PWM_INTSTAT_MR4: Interrupt flag for PWM match channel 4
* - PWM_INTSTAT_MR5: Interrupt flag for PWM match channel 5
* - PWM_INTSTAT_MR6: Interrupt flag for PWM match channel 6
* - PWM_INTSTAT_CAP0: Interrupt flag for capture input 0
* - PWM_INTSTAT_CAP1: Interrupt flag for capture input 1
* @return New State of PWM interrupt flag (SET or RESET)
**********************************************************************/
IntStatus PWM_GetIntStatus(LPC_PWM_TypeDef *PWMx, uint32_t IntFlag)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM_INTSTAT(IntFlag));
return ((PWMx->IR & IntFlag) ? SET : RESET);
}
/*********************************************************************//**
* @brief Clear specified PWM Interrupt pending
* @param[in] PWMx: PWM peripheral, should be LPC_PWM1
* @param[in] IntFlag: PWM interrupt flag, should be:
* - PWM_INTSTAT_MR0: Interrupt flag for PWM match channel 0
* - PWM_INTSTAT_MR1: Interrupt flag for PWM match channel 1
* - PWM_INTSTAT_MR2: Interrupt flag for PWM match channel 2
* - PWM_INTSTAT_MR3: Interrupt flag for PWM match channel 3
* - PWM_INTSTAT_MR4: Interrupt flag for PWM match channel 4
* - PWM_INTSTAT_MR5: Interrupt flag for PWM match channel 5
* - PWM_INTSTAT_MR6: Interrupt flag for PWM match channel 6
* - PWM_INTSTAT_CAP0: Interrupt flag for capture input 0
* - PWM_INTSTAT_CAP1: Interrupt flag for capture input 1
* @return None
**********************************************************************/
void PWM_ClearIntPending(LPC_PWM_TypeDef *PWMx, uint32_t IntFlag)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM_INTSTAT(IntFlag));
PWMx->IR = IntFlag;
}
/*****************************************************************************//**
* @brief Fills each PWM_InitStruct member with its default value:
* - If PWMCounterMode = PWM_MODE_TIMER:
* + PrescaleOption = PWM_TIMER_PRESCALE_USVAL
* + PrescaleValue = 1
* - If PWMCounterMode = PWM_MODE_COUNTER:
* + CountInputSelect = PWM_COUNTER_PCAP1_0
* + CounterOption = PWM_COUNTER_RISING
* @param[in] PWMTimerCounterMode Timer or Counter mode, should be:
* - PWM_MODE_TIMER: Counter of PWM peripheral is in Timer mode
* - PWM_MODE_COUNTER: Counter of PWM peripheral is in Counter mode
* @param[in] PWM_InitStruct Pointer to structure (PWM_TIMERCFG_Type or
* PWM_COUNTERCFG_Type) which will be initialized.
* @return None
* Note: PWM_InitStruct pointer will be assigned to corresponding structure
* (PWM_TIMERCFG_Type or PWM_COUNTERCFG_Type) due to PWMTimerCounterMode.
*******************************************************************************/
void PWM_ConfigStructInit(uint8_t PWMTimerCounterMode, void *PWM_InitStruct)
{
PWM_TIMERCFG_Type *pTimeCfg;
PWM_COUNTERCFG_Type *pCounterCfg;
CHECK_PARAM(PARAM_PWM_TC_MODE(PWMTimerCounterMode));
pTimeCfg = (PWM_TIMERCFG_Type *) PWM_InitStruct;
pCounterCfg = (PWM_COUNTERCFG_Type *) PWM_InitStruct;
if (PWMTimerCounterMode == PWM_MODE_TIMER )
{
pTimeCfg->PrescaleOption = PWM_TIMER_PRESCALE_USVAL;
pTimeCfg->PrescaleValue = 1;
}
else if (PWMTimerCounterMode == PWM_MODE_COUNTER)
{
pCounterCfg->CountInputSelect = PWM_COUNTER_PCAP1_0;
pCounterCfg->CounterOption = PWM_COUNTER_RISING;
}
}
/*********************************************************************//**
* @brief Initializes the PWMx peripheral corresponding to the specified
* parameters in the PWM_ConfigStruct.
* @param[in] PWMx PWM peripheral, should be LPC_PWM1
* @param[in] PWMTimerCounterMode Timer or Counter mode, should be:
* - PWM_MODE_TIMER: Counter of PWM peripheral is in Timer mode
* - PWM_MODE_COUNTER: Counter of PWM peripheral is in Counter mode
* @param[in] PWM_ConfigStruct Pointer to structure (PWM_TIMERCFG_Type or
* PWM_COUNTERCFG_Type) which will be initialized.
* @return None
* Note: PWM_ConfigStruct pointer will be assigned to corresponding structure
* (PWM_TIMERCFG_Type or PWM_COUNTERCFG_Type) due to PWMTimerCounterMode.
**********************************************************************/
void PWM_Init(LPC_PWM_TypeDef *PWMx, uint32_t PWMTimerCounterMode, void *PWM_ConfigStruct)
{
PWM_TIMERCFG_Type *pTimeCfg;
PWM_COUNTERCFG_Type *pCounterCfg;
uint64_t clkdlycnt;
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM_TC_MODE(PWMTimerCounterMode));
pTimeCfg = (PWM_TIMERCFG_Type *)PWM_ConfigStruct;
pCounterCfg = (PWM_COUNTERCFG_Type *)PWM_ConfigStruct;
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM1, ENABLE);
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_PWM1, CLKPWR_PCLKSEL_CCLK_DIV_4);
// Get peripheral clock of PWM1
clkdlycnt = (uint64_t) CLKPWR_GetPCLK (CLKPWR_PCLKSEL_PWM1);
// Clear all interrupts pending
PWMx->IR = 0xFF & PWM_IR_BITMASK;
PWMx->TCR = 0x00;
PWMx->CTCR = 0x00;
PWMx->MCR = 0x00;
PWMx->CCR = 0x00;
PWMx->PCR = 0x00;
PWMx->LER = 0x00;
if (PWMTimerCounterMode == PWM_MODE_TIMER)
{
CHECK_PARAM(PARAM_PWM_TIMER_PRESCALE(pTimeCfg->PrescaleOption));
/* Absolute prescale value */
if (pTimeCfg->PrescaleOption == PWM_TIMER_PRESCALE_TICKVAL)
{
PWMx->PR = pTimeCfg->PrescaleValue - 1;
}
/* uSecond prescale value */
else
{
clkdlycnt = (clkdlycnt * pTimeCfg->PrescaleValue) / 1000000;
PWMx->PR = ((uint32_t) clkdlycnt) - 1;
}
}
else if (PWMTimerCounterMode == PWM_MODE_COUNTER)
{
CHECK_PARAM(PARAM_PWM_COUNTER_INPUTSEL(pCounterCfg->CountInputSelect));
CHECK_PARAM(PARAM_PWM_COUNTER_EDGE(pCounterCfg->CounterOption));
PWMx->CTCR |= (PWM_CTCR_MODE((uint32_t)pCounterCfg->CounterOption)) \
| (PWM_CTCR_SELECT_INPUT((uint32_t)pCounterCfg->CountInputSelect));
}
}
/*********************************************************************//**
* @brief De-initializes the PWM peripheral registers to their
* default reset values.
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @return None
**********************************************************************/
void PWM_DeInit (LPC_PWM_TypeDef *PWMx)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
// Disable PWM control (timer, counter and PWM)
PWMx->TCR = 0x00;
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCPWM1, DISABLE);
}
/*********************************************************************//**
* @brief Enable/Disable PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] NewState New State of this function, should be:
* - ENABLE: Enable PWM peripheral
* - DISABLE: Disable PWM peripheral
* @return None
**********************************************************************/
void PWM_Cmd(LPC_PWM_TypeDef *PWMx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (NewState == ENABLE)
{
PWMx->TCR |= PWM_TCR_PWM_ENABLE;
}
else
{
PWMx->TCR &= (~PWM_TCR_PWM_ENABLE) & PWM_TCR_BITMASK;
}
}
/*********************************************************************//**
* @brief Enable/Disable Counter in PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] NewState New State of this function, should be:
* - ENABLE: Enable Counter in PWM peripheral
* - DISABLE: Disable Counter in PWM peripheral
* @return None
**********************************************************************/
void PWM_CounterCmd(LPC_PWM_TypeDef *PWMx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (NewState == ENABLE)
{
PWMx->TCR |= PWM_TCR_COUNTER_ENABLE;
}
else
{
PWMx->TCR &= (~PWM_TCR_COUNTER_ENABLE) & PWM_TCR_BITMASK;
}
}
/*********************************************************************//**
* @brief Reset Counter in PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @return None
**********************************************************************/
void PWM_ResetCounter(LPC_PWM_TypeDef *PWMx)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
PWMx->TCR |= PWM_TCR_COUNTER_RESET;
PWMx->TCR &= (~PWM_TCR_COUNTER_RESET) & PWM_TCR_BITMASK;
}
/*********************************************************************//**
* @brief Configures match for PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] PWM_MatchConfigStruct Pointer to a PWM_MATCHCFG_Type structure
* that contains the configuration information for the
* specified PWM match function.
* @return None
**********************************************************************/
void PWM_ConfigMatch(LPC_PWM_TypeDef *PWMx, PWM_MATCHCFG_Type *PWM_MatchConfigStruct)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_MATCH_CHANNEL(PWM_MatchConfigStruct->MatchChannel));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_MatchConfigStruct->IntOnMatch));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_MatchConfigStruct->ResetOnMatch));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_MatchConfigStruct->StopOnMatch));
//interrupt on MRn
if (PWM_MatchConfigStruct->IntOnMatch == ENABLE)
{
PWMx->MCR |= PWM_MCR_INT_ON_MATCH(PWM_MatchConfigStruct->MatchChannel);
}
else
{
PWMx->MCR &= (~PWM_MCR_INT_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \
& PWM_MCR_BITMASK;
}
//reset on MRn
if (PWM_MatchConfigStruct->ResetOnMatch == ENABLE)
{
PWMx->MCR |= PWM_MCR_RESET_ON_MATCH(PWM_MatchConfigStruct->MatchChannel);
}
else
{
PWMx->MCR &= (~PWM_MCR_RESET_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \
& PWM_MCR_BITMASK;
}
//stop on MRn
if (PWM_MatchConfigStruct->StopOnMatch == ENABLE)
{
PWMx->MCR |= PWM_MCR_STOP_ON_MATCH(PWM_MatchConfigStruct->MatchChannel);
}
else
{
PWMx->MCR &= (~PWM_MCR_STOP_ON_MATCH(PWM_MatchConfigStruct->MatchChannel)) \
& PWM_MCR_BITMASK;
}
}
/*********************************************************************//**
* @brief Configures capture input for PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] PWM_CaptureConfigStruct Pointer to a PWM_CAPTURECFG_Type structure
* that contains the configuration information for the
* specified PWM capture input function.
* @return None
**********************************************************************/
void PWM_ConfigCapture(LPC_PWM_TypeDef *PWMx, PWM_CAPTURECFG_Type *PWM_CaptureConfigStruct)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_CAPTURE_CHANNEL(PWM_CaptureConfigStruct->CaptureChannel));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_CaptureConfigStruct->FallingEdge));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_CaptureConfigStruct->IntOnCaption));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(PWM_CaptureConfigStruct->RisingEdge));
if (PWM_CaptureConfigStruct->RisingEdge == ENABLE)
{
PWMx->CCR |= PWM_CCR_CAP_RISING(PWM_CaptureConfigStruct->CaptureChannel);
}
else
{
PWMx->CCR &= (~PWM_CCR_CAP_RISING(PWM_CaptureConfigStruct->CaptureChannel)) \
& PWM_CCR_BITMASK;
}
if (PWM_CaptureConfigStruct->FallingEdge == ENABLE)
{
PWMx->CCR |= PWM_CCR_CAP_FALLING(PWM_CaptureConfigStruct->CaptureChannel);
}
else
{
PWMx->CCR &= (~PWM_CCR_CAP_FALLING(PWM_CaptureConfigStruct->CaptureChannel)) \
& PWM_CCR_BITMASK;
}
if (PWM_CaptureConfigStruct->IntOnCaption == ENABLE)
{
PWMx->CCR |= PWM_CCR_INT_ON_CAP(PWM_CaptureConfigStruct->CaptureChannel);
}
else
{
PWMx->CCR &= (~PWM_CCR_INT_ON_CAP(PWM_CaptureConfigStruct->CaptureChannel)) \
& PWM_CCR_BITMASK;
}
}
/*********************************************************************//**
* @brief Read value of capture register PWM peripheral
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] CaptureChannel: capture channel number, should be in
* range 0 to 1
* @return Value of capture register
**********************************************************************/
uint32_t PWM_GetCaptureValue(LPC_PWM_TypeDef *PWMx, uint8_t CaptureChannel)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_CAPTURE_CHANNEL(CaptureChannel));
switch (CaptureChannel)
{
case 0:
return PWMx->CR0;
case 1:
return PWMx->CR1;
default:
return (0);
}
}
/********************************************************************//**
* @brief Update value for each PWM channel with update type option
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] MatchChannel Match channel
* @param[in] MatchValue Match value
* @param[in] UpdateType Type of Update, should be:
* - PWM_MATCH_UPDATE_NOW: The update value will be updated for
* this channel immediately
* - PWM_MATCH_UPDATE_NEXT_RST: The update value will be updated for
* this channel on next reset by a PWM Match event.
* @return None
*********************************************************************/
void PWM_MatchUpdate(LPC_PWM_TypeDef *PWMx, uint8_t MatchChannel, \
uint32_t MatchValue, uint8_t UpdateType)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_MATCH_CHANNEL(MatchChannel));
CHECK_PARAM(PARAM_PWM_MATCH_UPDATE(UpdateType));
switch (MatchChannel)
{
case 0:
PWMx->MR0 = MatchValue;
break;
case 1:
PWMx->MR1 = MatchValue;
break;
case 2:
PWMx->MR2 = MatchValue;
break;
case 3:
PWMx->MR3 = MatchValue;
break;
case 4:
PWMx->MR4 = MatchValue;
break;
case 5:
PWMx->MR5 = MatchValue;
break;
case 6:
PWMx->MR6 = MatchValue;
break;
}
// Write Latch register
PWMx->LER |= PWM_LER_EN_MATCHn_LATCH(MatchChannel);
// In case of update now
if (UpdateType == PWM_MATCH_UPDATE_NOW)
{
PWMx->TCR |= PWM_TCR_COUNTER_RESET;
PWMx->TCR &= (~PWM_TCR_COUNTER_RESET) & PWM_TCR_BITMASK;
}
}
/********************************************************************//**
* @brief Update value for multi PWM channel with update type option
* at the same time
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] MatchStruct Structure that contents match value of 7 pwm channels
* @param[in] UpdateType Type of Update, should be:
* - PWM_MATCH_UPDATE_NOW: The update value will be updated for
* this channel immediately
* - PWM_MATCH_UPDATE_NEXT_RST: The update value will be updated for
* this channel on next reset by a PWM Match event.
* @return None
*********************************************************************/
void PWM_MultiMatchUpdate(LPC_PWM_TypeDef *PWMx, PWM_Match_T *MatchStruct , uint8_t UpdateType)
{
uint8_t LatchValue = 0;
uint8_t i;
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM_MATCH_UPDATE(UpdateType));
//Update match value
for(i=0;i<7;i++)
{
if(MatchStruct[i].Status == SET)
{
if(i<4)
*((volatile unsigned int *)(&(PWMx->MR0) + i)) = MatchStruct[i].Matchvalue;
else
{
*((volatile unsigned int *)(&(PWMx->MR4) + (i-4))) = MatchStruct[i].Matchvalue;
}
LatchValue |=(1<<i);
}
}
//set update for multi-channel at the same time
PWMx->LER = LatchValue;
// In case of update now
if (UpdateType == PWM_MATCH_UPDATE_NOW)
{
PWMx->TCR |= PWM_TCR_COUNTER_RESET;
PWMx->TCR &= (~PWM_TCR_COUNTER_RESET) & PWM_TCR_BITMASK;
}
}
/********************************************************************//**
* @brief Configure Edge mode for each PWM channel
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] PWMChannel PWM channel, should be in range from 2 to 6
* @param[in] ModeOption PWM mode option, should be:
* - PWM_CHANNEL_SINGLE_EDGE: Single Edge mode
* - PWM_CHANNEL_DUAL_EDGE: Dual Edge mode
* @return None
* Note: PWM Channel 1 can not be selected for mode option
*********************************************************************/
void PWM_ChannelConfig(LPC_PWM_TypeDef *PWMx, uint8_t PWMChannel, uint8_t ModeOption)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_EDGE_MODE_CHANNEL(PWMChannel));
CHECK_PARAM(PARAM_PWM_CHANNEL_EDGE(ModeOption));
// Single edge mode
if (ModeOption == PWM_CHANNEL_SINGLE_EDGE)
{
PWMx->PCR &= (~PWM_PCR_PWMSELn(PWMChannel)) & PWM_PCR_BITMASK;
}
// Double edge mode
else if (PWM_CHANNEL_DUAL_EDGE)
{
PWMx->PCR |= PWM_PCR_PWMSELn(PWMChannel);
}
}
/********************************************************************//**
* @brief Enable/Disable PWM channel output
* @param[in] PWMx PWM peripheral selected, should be LPC_PWM1
* @param[in] PWMChannel PWM channel, should be in range from 1 to 6
* @param[in] NewState New State of this function, should be:
* - ENABLE: Enable this PWM channel output
* - DISABLE: Disable this PWM channel output
* @return None
*********************************************************************/
void PWM_ChannelCmd(LPC_PWM_TypeDef *PWMx, uint8_t PWMChannel, FunctionalState NewState)
{
CHECK_PARAM(PARAM_PWMx(PWMx));
CHECK_PARAM(PARAM_PWM1_CHANNEL(PWMChannel));
if (NewState == ENABLE)
{
PWMx->PCR |= PWM_PCR_PWMENAn(PWMChannel);
}
else
{
PWMx->PCR &= (~PWM_PCR_PWMENAn(PWMChannel)) & PWM_PCR_BITMASK;
}
}
/**
* @}
*/
#endif /* _PWM */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,514 @@
/**********************************************************************
* $Id$ lpc17xx_qei.c 2010-05-21
*//**
* @file lpc17xx_qei.c
* @brief Contains all functions support for QEI 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 QEI
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_qei.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 _QEI
/* Private Types -------------------------------------------------------------- */
/** @defgroup QEI_Private_Types QEI Private Types
* @{
*/
/**
* @brief QEI configuration union type definition
*/
typedef union {
QEI_CFG_Type bmQEIConfig;
uint32_t ulQEIConfig;
} QEI_CFGOPT_Type;
/**
* @}
*/
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup QEI_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Resets value for each type of QEI value, such as velocity,
* counter, position, etc..
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulResetType QEI Reset Type, should be one of the following:
* - QEI_RESET_POS: Reset Position Counter
* - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal
* - QEI_RESET_VEL: Reset Velocity
* - QEI_RESET_IDX: Reset Index Counter
* @return None
**********************************************************************/
void QEI_Reset(LPC_QEI_TypeDef *QEIx, uint32_t ulResetType)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_RESET(ulResetType));
QEIx->QEICON = ulResetType;
}
/*********************************************************************//**
* @brief Initializes the QEI peripheral according to the specified
* parameters in the QEI_ConfigStruct.
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] QEI_ConfigStruct Pointer to a QEI_CFG_Type structure
* that contains the configuration information for the
* specified QEI peripheral
* @return None
**********************************************************************/
void QEI_Init(LPC_QEI_TypeDef *QEIx, QEI_CFG_Type *QEI_ConfigStruct)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_DIRINV(QEI_ConfigStruct->DirectionInvert));
CHECK_PARAM(PARAM_QEI_SIGNALMODE(QEI_ConfigStruct->SignalMode));
CHECK_PARAM(PARAM_QEI_CAPMODE(QEI_ConfigStruct->CaptureMode));
CHECK_PARAM(PARAM_QEI_INVINX(QEI_ConfigStruct->InvertIndex));
/* Set up clock and power for QEI module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, ENABLE);
/* As default, peripheral clock for QEI module
* is set to FCCLK / 2 */
CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_QEI, CLKPWR_PCLKSEL_CCLK_DIV_1);
// Reset all remaining value in QEI peripheral
QEIx->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
QEIx->QEIMAXPOS = 0x00;
QEIx->CMPOS0 = 0x00;
QEIx->CMPOS1 = 0x00;
QEIx->CMPOS2 = 0x00;
QEIx->INXCMP = 0x00;
QEIx->QEILOAD = 0x00;
QEIx->VELCOMP = 0x00;
QEIx->FILTER = 0x00;
// Disable all Interrupt
QEIx->QEIIEC = QEI_IECLR_BITMASK;
// Clear all Interrupt pending
QEIx->QEICLR = QEI_INTCLR_BITMASK;
// Set QEI configuration value corresponding to its setting up value
QEIx->QEICONF = ((QEI_CFGOPT_Type *)QEI_ConfigStruct)->ulQEIConfig;
}
/*********************************************************************//**
* @brief De-initializes the QEI peripheral registers to their
* default reset values.
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return None
**********************************************************************/
void QEI_DeInit(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
/* Turn off clock and power for QEI module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, DISABLE);
}
/*****************************************************************************//**
* @brief Fills each QIE_InitStruct member with its default value:
* - DirectionInvert = QEI_DIRINV_NONE
* - SignalMode = QEI_SIGNALMODE_QUAD
* - CaptureMode = QEI_CAPMODE_4X
* - InvertIndex = QEI_INVINX_NONE
* @param[in] QIE_InitStruct Pointer to a QEI_CFG_Type structure
* which will be initialized.
* @return None
*******************************************************************************/
void QEI_ConfigStructInit(QEI_CFG_Type *QIE_InitStruct)
{
QIE_InitStruct->CaptureMode = QEI_CAPMODE_4X;
QIE_InitStruct->DirectionInvert = QEI_DIRINV_NONE;
QIE_InitStruct->InvertIndex = QEI_INVINX_NONE;
QIE_InitStruct->SignalMode = QEI_SIGNALMODE_QUAD;
}
/*********************************************************************//**
* @brief Check whether if specified flag status is set or not
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulFlagType Status Flag Type, should be one of the following:
* - QEI_STATUS_DIR: Direction Status
* @return New Status of this status flag (SET or RESET)
**********************************************************************/
FlagStatus QEI_GetStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulFlagType)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_STATUS(ulFlagType));
return ((QEIx->QEISTAT & ulFlagType) ? SET : RESET);
}
/*********************************************************************//**
* @brief Get current position value in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return Current position value of QEI peripheral
**********************************************************************/
uint32_t QEI_GetPosition(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
return (QEIx->QEIPOS);
}
/*********************************************************************//**
* @brief Set max position value for QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulMaxPos Max position value to set
* @return None
**********************************************************************/
void QEI_SetMaxPosition(LPC_QEI_TypeDef *QEIx, uint32_t ulMaxPos)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
QEIx->QEIMAXPOS = ulMaxPos;
}
/*********************************************************************//**
* @brief Set position compare value for QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] bPosCompCh Compare Position channel, should be:
* - QEI_COMPPOS_CH_0: QEI compare position channel 0
* - QEI_COMPPOS_CH_1: QEI compare position channel 1
* - QEI_COMPPOS_CH_2: QEI compare position channel 2
* @param[in] ulPosComp Compare Position value to set
* @return None
**********************************************************************/
void QEI_SetPositionComp(LPC_QEI_TypeDef *QEIx, uint8_t bPosCompCh, uint32_t ulPosComp)
{
uint32_t *tmp;
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_COMPPOS_CH(bPosCompCh));
tmp = (uint32_t *) (&(QEIx->CMPOS0) + bPosCompCh * 4);
*tmp = ulPosComp;
}
/*********************************************************************//**
* @brief Get current index counter of QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return Current value of QEI index counter
**********************************************************************/
uint32_t QEI_GetIndex(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
return (QEIx->INXCNT);
}
/*********************************************************************//**
* @brief Set value for index compare in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulIndexComp Compare Index Value to set
* @return None
**********************************************************************/
void QEI_SetIndexComp(LPC_QEI_TypeDef *QEIx, uint32_t ulIndexComp)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
QEIx->INXCMP = ulIndexComp;
}
/*********************************************************************//**
* @brief Set timer reload value for QEI peripheral. When the velocity timer is
* over-flow, the value that set for Timer Reload register will be loaded
* into the velocity timer for next period. The calculated velocity in RPM
* therefore will be affect by this value.
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] QEIReloadStruct QEI reload structure
* @return None
**********************************************************************/
void QEI_SetTimerReload(LPC_QEI_TypeDef *QEIx, QEI_RELOADCFG_Type *QEIReloadStruct)
{
uint64_t pclk;
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_TIMERRELOAD(QEIReloadStruct->ReloadOption));
if (QEIReloadStruct->ReloadOption == QEI_TIMERRELOAD_TICKVAL) {
QEIx->QEILOAD = QEIReloadStruct->ReloadValue - 1;
} else {
pclk = (uint64_t)CLKPWR_GetPCLK(CLKPWR_PCLKSEL_QEI);
pclk = (pclk /(1000000/QEIReloadStruct->ReloadValue)) - 1;
QEIx->QEILOAD = (uint32_t)pclk;
}
}
/*********************************************************************//**
* @brief Get current timer counter in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return Current timer counter in QEI peripheral
**********************************************************************/
uint32_t QEI_GetTimer(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
return (QEIx->QEITIME);
}
/*********************************************************************//**
* @brief Get current velocity pulse counter in current time period
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return Current velocity pulse counter value
**********************************************************************/
uint32_t QEI_GetVelocity(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
return (QEIx->QEIVEL);
}
/*********************************************************************//**
* @brief Get the most recently measured velocity of the QEI. When
* the Velocity timer in QEI is over-flow, the current velocity
* value will be loaded into Velocity Capture register.
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @return The most recently measured velocity value
**********************************************************************/
uint32_t QEI_GetVelocityCap(LPC_QEI_TypeDef *QEIx)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
return (QEIx->QEICAP);
}
/*********************************************************************//**
* @brief Set Velocity Compare value for QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulVelComp Compare Velocity value to set
* @return None
**********************************************************************/
void QEI_SetVelocityComp(LPC_QEI_TypeDef *QEIx, uint32_t ulVelComp)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
QEIx->VELCOMP = ulVelComp;
}
/*********************************************************************//**
* @brief Set value of sampling count for the digital filter in
* QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulSamplingPulse Value of sampling count to set
* @return None
**********************************************************************/
void QEI_SetDigiFilter(LPC_QEI_TypeDef *QEIx, uint32_t ulSamplingPulse)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
QEIx->FILTER = ulSamplingPulse;
}
/*********************************************************************//**
* @brief Check whether if specified interrupt flag status in QEI
* peripheral is set or not
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulIntType Interrupt Flag Status type, should be:
- QEI_INTFLAG_INX_Int: index pulse was detected interrupt
- QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
- QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
- QEI_INTFLAG_DIR_Int: Change of direction interrupt
- QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
- QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
- QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
current position interrupt
- QEI_INTFLAG_REV_Int: Index compare value is equal to the current
index count interrupt
- QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
- QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
- QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
* @return New State of specified interrupt flag status (SET or RESET)
**********************************************************************/
FlagStatus QEI_GetIntStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType));
return((QEIx->QEIINTSTAT & ulIntType) ? SET : RESET);
}
/*********************************************************************//**
* @brief Enable/Disable specified interrupt in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulIntType Interrupt Flag Status type, should be:
* - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
* - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
* - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
* - QEI_INTFLAG_DIR_Int: Change of direction interrupt
* - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
* - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
* - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
* current position interrupt
* - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
* current position interrupt
* - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
* current position interrupt
* - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
* index count interrupt
* - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
* - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
* - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
* @param[in] NewState New function state, should be:
* - DISABLE
* - ENABLE
* @return None
**********************************************************************/
void QEI_IntCmd(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType, FunctionalState NewState)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (NewState == ENABLE) {
QEIx->QEIIES = ulIntType;
} else {
QEIx->QEIIEC = ulIntType;
}
}
/*********************************************************************//**
* @brief Sets (forces) specified interrupt in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulIntType Interrupt Flag Status type, should be:
- QEI_INTFLAG_INX_Int: index pulse was detected interrupt
- QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
- QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
- QEI_INTFLAG_DIR_Int: Change of direction interrupt
- QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
- QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
- QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
current position interrupt
- QEI_INTFLAG_REV_Int: Index compare value is equal to the current
index count interrupt
- QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
- QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
- QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
* @return None
**********************************************************************/
void QEI_IntSet(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType));
QEIx->QEISET = ulIntType;
}
/*********************************************************************//**
* @brief Clear (force) specified interrupt (pending) in QEI peripheral
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulIntType Interrupt Flag Status type, should be:
- QEI_INTFLAG_INX_Int: index pulse was detected interrupt
- QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
- QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
- QEI_INTFLAG_DIR_Int: Change of direction interrupt
- QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
- QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
- QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
current position interrupt
- QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
current position interrupt
- QEI_INTFLAG_REV_Int: Index compare value is equal to the current
index count interrupt
- QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
- QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
- QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
* @return None
**********************************************************************/
void QEI_IntClear(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType)
{
CHECK_PARAM(PARAM_QEIx(QEIx));
CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType));
QEIx->QEICLR = ulIntType;
}
/*********************************************************************//**
* @brief Calculates the actual velocity in RPM passed via velocity
* capture value and Pulse Per Round (of the encoder) value
* parameter input.
* @param[in] QEIx QEI peripheral, should be LPC_QEI
* @param[in] ulVelCapValue Velocity capture input value that can
* be got from QEI_GetVelocityCap() function
* @param[in] ulPPR Pulse per round of encoder
* @return The actual value of velocity in RPM (Round per minute)
**********************************************************************/
uint32_t QEI_CalculateRPM(LPC_QEI_TypeDef *QEIx, uint32_t ulVelCapValue, uint32_t ulPPR)
{
uint64_t rpm, clock, Load, edges;
// Get current Clock rate for timer input
clock = (uint64_t)CLKPWR_GetPCLK(CLKPWR_PCLKSEL_QEI);
// Get Timer load value (velocity capture period)
Load = (uint64_t)(QEIx->QEILOAD + 1);
// Get Edge
edges = (uint64_t)((QEIx->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2);
// Calculate RPM
rpm = ((clock * ulVelCapValue * 60) / (Load * ulPPR * edges));
return (uint32_t)(rpm);
}
/**
* @}
*/
#endif /* _QEI */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,199 @@
/**********************************************************************
* $Id$ lpc17xx_rit.c 2010-05-21
*//**
* @file lpc17xx_rit.c
* @brief Contains all functions support for RIT 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 RIT
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_rit.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 _RIT
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup RIT_Public_Functions
* @{
*/
/******************************************************************************//*
* @brief Initial for RIT
* - Turn on power and clock
* - Setup default register values
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @return None
*******************************************************************************/
void RIT_Init(LPC_RIT_TypeDef *RITx)
{
CHECK_PARAM(PARAM_RITx(RITx));
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRIT, ENABLE);
//Set up default register values
RITx->RICOMPVAL = 0xFFFFFFFF;
RITx->RIMASK = 0x00000000;
RITx->RICTRL = 0x0C;
RITx->RICOUNTER = 0x00000000;
// Turn on power and clock
}
/******************************************************************************//*
* @brief DeInitial for RIT
* - Turn off power and clock
* - ReSetup default register values
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @return None
*******************************************************************************/
void RIT_DeInit(LPC_RIT_TypeDef *RITx)
{
CHECK_PARAM(PARAM_RITx(RITx));
// Turn off power and clock
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRIT, DISABLE);
//ReSetup default register values
RITx->RICOMPVAL = 0xFFFFFFFF;
RITx->RIMASK = 0x00000000;
RITx->RICTRL = 0x0C;
RITx->RICOUNTER = 0x00000000;
}
/******************************************************************************//*
* @brief Set compare value, mask value and time counter value
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @param[in] time_interval: timer interval value (ms)
* @return None
*******************************************************************************/
void RIT_TimerConfig(LPC_RIT_TypeDef *RITx, uint32_t time_interval)
{
uint32_t clock_rate, cmp_value;
CHECK_PARAM(PARAM_RITx(RITx));
// Get PCLK value of RIT
clock_rate = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_RIT);
/* calculate compare value for RIT to generate interrupt at
* specified time interval
* COMPVAL = (RIT_PCLK * time_interval)/1000
* (with time_interval unit is millisecond)
*/
cmp_value = (clock_rate /1000) * time_interval;
RITx->RICOMPVAL = cmp_value;
/* Set timer enable clear bit to clear timer to 0 whenever
* counter value equals the contents of RICOMPVAL
*/
RITx->RICTRL |= (1<<1);
}
/******************************************************************************//*
* @brief Enable/Disable Timer
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @param[in] NewState New State of this function
* -ENABLE: Enable Timer
* -DISABLE: Disable Timer
* @return None
*******************************************************************************/
void RIT_Cmd(LPC_RIT_TypeDef *RITx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_RITx(RITx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
//Enable or Disable Timer
if(NewState==ENABLE)
{
RITx->RICTRL |= RIT_CTRL_TEN;
}
else
{
RITx->RICTRL &= ~RIT_CTRL_TEN;
}
}
/******************************************************************************//*
* @brief Timer Enable/Disable on debug
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @param[in] NewState New State of this function
* -ENABLE: The timer is halted whenever a hardware break condition occurs
* -DISABLE: Hardware break has no effect on the timer operation
* @return None
*******************************************************************************/
void RIT_TimerDebugCmd(LPC_RIT_TypeDef *RITx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_RITx(RITx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
//Timer Enable/Disable on break
if(NewState==ENABLE)
{
RITx->RICTRL |= RIT_CTRL_ENBR;
}
else
{
RITx->RICTRL &= ~RIT_CTRL_ENBR;
}
}
/******************************************************************************//*
* @brief Check whether interrupt flag is set or not
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
* @return Current interrupt status, could be: SET/RESET
*******************************************************************************/
IntStatus RIT_GetIntStatus(LPC_RIT_TypeDef *RITx)
{
IntStatus result;
CHECK_PARAM(PARAM_RITx(RITx));
if((RITx->RICTRL&RIT_CTRL_INTEN)==1) result= SET;
else return RESET;
//clear interrupt flag
RITx->RICTRL |= RIT_CTRL_INTEN;
return result;
}
/**
* @}
*/
#endif /* _RIT */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,783 @@
/**********************************************************************
* $Id$ lpc17xx_rtc.c 2011-06-06
*//**
* @file lpc17xx_rtc.c
* @brief Contains all functions support for RTC firmware library on LPC17xx
* @version 3.1
* @date 6. June. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, 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 RTC
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_rtc.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 _RTC
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup RTC_Public_Functions
* @{
*/
/********************************************************************//**
* @brief Initializes the RTC peripheral.
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @return None
*********************************************************************/
void RTC_Init (LPC_RTC_TypeDef *RTCx)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
/* Set up clock and power for RTC module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, ENABLE);
// Clear all register to be default
RTCx->ILR = 0x00;
RTCx->CCR = 0x00;
RTCx->CIIR = 0x00;
RTCx->AMR = 0xFF;
RTCx->CALIBRATION = 0x00;
}
/*********************************************************************//**
* @brief De-initializes the RTC peripheral registers to their
* default reset values.
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @return None
**********************************************************************/
void RTC_DeInit(LPC_RTC_TypeDef *RTCx)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
RTCx->CCR = 0x00;
// Disable power and clock for RTC module
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, DISABLE);
}
/*********************************************************************//**
* @brief Reset clock tick counter in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @return None
**********************************************************************/
void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
RTCx->CCR |= RTC_CCR_CTCRST;
RTCx->CCR &= (~RTC_CCR_CTCRST) & RTC_CCR_BITMASK;
}
/*********************************************************************//**
* @brief Start/Stop RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] NewState New State of this function, should be:
* - ENABLE: The time counters are enabled
* - DISABLE: The time counters are disabled
* @return None
**********************************************************************/
void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (NewState == ENABLE)
{
RTCx->CCR |= RTC_CCR_CLKEN;
}
else
{
RTCx->CCR &= (~RTC_CCR_CLKEN) & RTC_CCR_BITMASK;
}
}
/*********************************************************************//**
* @brief Enable/Disable Counter increment interrupt for each time type
* in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] CntIncrIntType: Counter Increment Interrupt type,
* an increment of this type value below will generates
* an interrupt, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @param[in] NewState New State of this function, should be:
* - ENABLE: Counter Increment interrupt for this
* time type are enabled
* - DISABLE: Counter Increment interrupt for this
* time type are disabled
* @return None
**********************************************************************/
void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \
FunctionalState NewState)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
CHECK_PARAM(PARAM_RTC_TIMETYPE(CntIncrIntType));
if (NewState == ENABLE)
{
switch (CntIncrIntType)
{
case RTC_TIMETYPE_SECOND:
RTCx->CIIR |= RTC_CIIR_IMSEC;
break;
case RTC_TIMETYPE_MINUTE:
RTCx->CIIR |= RTC_CIIR_IMMIN;
break;
case RTC_TIMETYPE_HOUR:
RTCx->CIIR |= RTC_CIIR_IMHOUR;
break;
case RTC_TIMETYPE_DAYOFWEEK:
RTCx->CIIR |= RTC_CIIR_IMDOW;
break;
case RTC_TIMETYPE_DAYOFMONTH:
RTCx->CIIR |= RTC_CIIR_IMDOM;
break;
case RTC_TIMETYPE_DAYOFYEAR:
RTCx->CIIR |= RTC_CIIR_IMDOY;
break;
case RTC_TIMETYPE_MONTH:
RTCx->CIIR |= RTC_CIIR_IMMON;
break;
case RTC_TIMETYPE_YEAR:
RTCx->CIIR |= RTC_CIIR_IMYEAR;
break;
}
}
else
{
switch (CntIncrIntType)
{
case RTC_TIMETYPE_SECOND:
RTCx->CIIR &= (~RTC_CIIR_IMSEC) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_MINUTE:
RTCx->CIIR &= (~RTC_CIIR_IMMIN) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_HOUR:
RTCx->CIIR &= (~RTC_CIIR_IMHOUR) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFWEEK:
RTCx->CIIR &= (~RTC_CIIR_IMDOW) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFMONTH:
RTCx->CIIR &= (~RTC_CIIR_IMDOM) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFYEAR:
RTCx->CIIR &= (~RTC_CIIR_IMDOY) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_MONTH:
RTCx->CIIR &= (~RTC_CIIR_IMMON) & RTC_CIIR_BITMASK;
break;
case RTC_TIMETYPE_YEAR:
RTCx->CIIR &= (~RTC_CIIR_IMYEAR) & RTC_CIIR_BITMASK;
break;
}
}
}
/*********************************************************************//**
* @brief Enable/Disable Alarm interrupt for each time type
* in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] AlarmTimeType: Alarm Time Interrupt type,
* an matching of this type value below with current time
* in RTC will generates an interrupt, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @param[in] NewState New State of this function, should be:
* - ENABLE: Alarm interrupt for this
* time type are enabled
* - DISABLE: Alarm interrupt for this
* time type are disabled
* @return None
**********************************************************************/
void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \
FunctionalState NewState)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
CHECK_PARAM(PARAM_RTC_TIMETYPE(AlarmTimeType));
if (NewState == ENABLE)
{
switch (AlarmTimeType)
{
case RTC_TIMETYPE_SECOND:
RTCx->AMR &= (~RTC_AMR_AMRSEC) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_MINUTE:
RTCx->AMR &= (~RTC_AMR_AMRMIN) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_HOUR:
RTCx->AMR &= (~RTC_AMR_AMRHOUR) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFWEEK:
RTCx->AMR &= (~RTC_AMR_AMRDOW) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFMONTH:
RTCx->AMR &= (~RTC_AMR_AMRDOM) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_DAYOFYEAR:
RTCx->AMR &= (~RTC_AMR_AMRDOY) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_MONTH:
RTCx->AMR &= (~RTC_AMR_AMRMON) & RTC_AMR_BITMASK;
break;
case RTC_TIMETYPE_YEAR:
RTCx->AMR &= (~RTC_AMR_AMRYEAR) & RTC_AMR_BITMASK;
break;
}
}
else
{
switch (AlarmTimeType)
{
case RTC_TIMETYPE_SECOND:
RTCx->AMR |= (RTC_AMR_AMRSEC);
break;
case RTC_TIMETYPE_MINUTE:
RTCx->AMR |= (RTC_AMR_AMRMIN);
break;
case RTC_TIMETYPE_HOUR:
RTCx->AMR |= (RTC_AMR_AMRHOUR);
break;
case RTC_TIMETYPE_DAYOFWEEK:
RTCx->AMR |= (RTC_AMR_AMRDOW);
break;
case RTC_TIMETYPE_DAYOFMONTH:
RTCx->AMR |= (RTC_AMR_AMRDOM);
break;
case RTC_TIMETYPE_DAYOFYEAR:
RTCx->AMR |= (RTC_AMR_AMRDOY);
break;
case RTC_TIMETYPE_MONTH:
RTCx->AMR |= (RTC_AMR_AMRMON);
break;
case RTC_TIMETYPE_YEAR:
RTCx->AMR |= (RTC_AMR_AMRYEAR);
break;
}
}
}
/*********************************************************************//**
* @brief Set current time value for each time type in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Timetype: Time Type, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @param[in] TimeValue Time value to set
* @return None
**********************************************************************/
void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));
switch ( Timetype)
{
case RTC_TIMETYPE_SECOND:
CHECK_PARAM(TimeValue <= RTC_SECOND_MAX);
RTCx->SEC = TimeValue & RTC_SEC_MASK;
break;
case RTC_TIMETYPE_MINUTE:
CHECK_PARAM(TimeValue <= RTC_MINUTE_MAX);
RTCx->MIN = TimeValue & RTC_MIN_MASK;
break;
case RTC_TIMETYPE_HOUR:
CHECK_PARAM(TimeValue <= RTC_HOUR_MAX);
RTCx->HOUR = TimeValue & RTC_HOUR_MASK;
break;
case RTC_TIMETYPE_DAYOFWEEK:
CHECK_PARAM(TimeValue <= RTC_DAYOFWEEK_MAX);
RTCx->DOW = TimeValue & RTC_DOW_MASK;
break;
case RTC_TIMETYPE_DAYOFMONTH:
CHECK_PARAM((TimeValue <= RTC_DAYOFMONTH_MAX) \
&& (TimeValue >= RTC_DAYOFMONTH_MIN));
RTCx->DOM = TimeValue & RTC_DOM_MASK;
break;
case RTC_TIMETYPE_DAYOFYEAR:
CHECK_PARAM((TimeValue >= RTC_DAYOFYEAR_MIN) \
&& (TimeValue <= RTC_DAYOFYEAR_MAX));
RTCx->DOY = TimeValue & RTC_DOY_MASK;
break;
case RTC_TIMETYPE_MONTH:
CHECK_PARAM((TimeValue >= RTC_MONTH_MIN) \
&& (TimeValue <= RTC_MONTH_MAX));
RTCx->MONTH = TimeValue & RTC_MONTH_MASK;
break;
case RTC_TIMETYPE_YEAR:
CHECK_PARAM(TimeValue <= RTC_YEAR_MAX);
RTCx->YEAR = TimeValue & RTC_YEAR_MASK;
break;
}
}
/*********************************************************************//**
* @brief Get current time value for each type time type
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Timetype: Time Type, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @return Value of time according to specified time type
**********************************************************************/
uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));
switch (Timetype)
{
case RTC_TIMETYPE_SECOND:
return (RTCx->SEC & RTC_SEC_MASK);
case RTC_TIMETYPE_MINUTE:
return (RTCx->MIN & RTC_MIN_MASK);
case RTC_TIMETYPE_HOUR:
return (RTCx->HOUR & RTC_HOUR_MASK);
case RTC_TIMETYPE_DAYOFWEEK:
return (RTCx->DOW & RTC_DOW_MASK);
case RTC_TIMETYPE_DAYOFMONTH:
return (RTCx->DOM & RTC_DOM_MASK);
case RTC_TIMETYPE_DAYOFYEAR:
return (RTCx->DOY & RTC_DOY_MASK);
case RTC_TIMETYPE_MONTH:
return (RTCx->MONTH & RTC_MONTH_MASK);
case RTC_TIMETYPE_YEAR:
return (RTCx->YEAR & RTC_YEAR_MASK);
default:
return (0);
}
}
/*********************************************************************//**
* @brief Set full of time in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
* contains time value in full.
* @return None
**********************************************************************/
void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
RTCx->DOM = pFullTime->DOM & RTC_DOM_MASK;
RTCx->DOW = pFullTime->DOW & RTC_DOW_MASK;
RTCx->DOY = pFullTime->DOY & RTC_DOY_MASK;
RTCx->HOUR = pFullTime->HOUR & RTC_HOUR_MASK;
RTCx->MIN = pFullTime->MIN & RTC_MIN_MASK;
RTCx->SEC = pFullTime->SEC & RTC_SEC_MASK;
RTCx->MONTH = pFullTime->MONTH & RTC_MONTH_MASK;
RTCx->YEAR = pFullTime->YEAR & RTC_YEAR_MASK;
}
/*********************************************************************//**
* @brief Get full of time in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
* will be stored time in full.
* @return None
**********************************************************************/
void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
pFullTime->DOM = RTCx->DOM & RTC_DOM_MASK;
pFullTime->DOW = RTCx->DOW & RTC_DOW_MASK;
pFullTime->DOY = RTCx->DOY & RTC_DOY_MASK;
pFullTime->HOUR = RTCx->HOUR & RTC_HOUR_MASK;
pFullTime->MIN = RTCx->MIN & RTC_MIN_MASK;
pFullTime->SEC = RTCx->SEC & RTC_SEC_MASK;
pFullTime->MONTH = RTCx->MONTH & RTC_MONTH_MASK;
pFullTime->YEAR = RTCx->YEAR & RTC_YEAR_MASK;
}
/*********************************************************************//**
* @brief Set alarm time value for each time type
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Timetype: Time Type, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @param[in] ALValue Alarm time value to set
* @return None
**********************************************************************/
void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
switch (Timetype)
{
case RTC_TIMETYPE_SECOND:
CHECK_PARAM(ALValue <= RTC_SECOND_MAX);
RTCx->ALSEC = ALValue & RTC_SEC_MASK;
break;
case RTC_TIMETYPE_MINUTE:
CHECK_PARAM(ALValue <= RTC_MINUTE_MAX);
RTCx->ALMIN = ALValue & RTC_MIN_MASK;
break;
case RTC_TIMETYPE_HOUR:
CHECK_PARAM(ALValue <= RTC_HOUR_MAX);
RTCx->ALHOUR = ALValue & RTC_HOUR_MASK;
break;
case RTC_TIMETYPE_DAYOFWEEK:
CHECK_PARAM(ALValue <= RTC_DAYOFWEEK_MAX);
RTCx->ALDOW = ALValue & RTC_DOW_MASK;
break;
case RTC_TIMETYPE_DAYOFMONTH:
CHECK_PARAM((ALValue <= RTC_DAYOFMONTH_MAX) \
&& (ALValue >= RTC_DAYOFMONTH_MIN));
RTCx->ALDOM = ALValue & RTC_DOM_MASK;
break;
case RTC_TIMETYPE_DAYOFYEAR:
CHECK_PARAM((ALValue >= RTC_DAYOFYEAR_MIN) \
&& (ALValue <= RTC_DAYOFYEAR_MAX));
RTCx->ALDOY = ALValue & RTC_DOY_MASK;
break;
case RTC_TIMETYPE_MONTH:
CHECK_PARAM((ALValue >= RTC_MONTH_MIN) \
&& (ALValue <= RTC_MONTH_MAX));
RTCx->ALMON = ALValue & RTC_MONTH_MASK;
break;
case RTC_TIMETYPE_YEAR:
CHECK_PARAM(ALValue <= RTC_YEAR_MAX);
RTCx->ALYEAR = ALValue & RTC_YEAR_MASK;
break;
}
}
/*********************************************************************//**
* @brief Get alarm time value for each time type
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Timetype: Time Type, should be:
* - RTC_TIMETYPE_SECOND
* - RTC_TIMETYPE_MINUTE
* - RTC_TIMETYPE_HOUR
* - RTC_TIMETYPE_DAYOFWEEK
* - RTC_TIMETYPE_DAYOFMONTH
* - RTC_TIMETYPE_DAYOFYEAR
* - RTC_TIMETYPE_MONTH
* - RTC_TIMETYPE_YEAR
* @return Value of Alarm time according to specified time type
**********************************************************************/
uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype)
{
switch (Timetype)
{
case RTC_TIMETYPE_SECOND:
return (RTCx->ALSEC & RTC_SEC_MASK);
case RTC_TIMETYPE_MINUTE:
return (RTCx->ALMIN & RTC_MIN_MASK);
case RTC_TIMETYPE_HOUR:
return (RTCx->ALHOUR & RTC_HOUR_MASK);
case RTC_TIMETYPE_DAYOFWEEK:
return (RTCx->ALDOW & RTC_DOW_MASK);
case RTC_TIMETYPE_DAYOFMONTH:
return (RTCx->ALDOM & RTC_DOM_MASK);
case RTC_TIMETYPE_DAYOFYEAR:
return (RTCx->ALDOY & RTC_DOY_MASK);
case RTC_TIMETYPE_MONTH:
return (RTCx->ALMON & RTC_MONTH_MASK);
case RTC_TIMETYPE_YEAR:
return (RTCx->ALYEAR & RTC_YEAR_MASK);
default:
return (0);
}
}
/*********************************************************************//**
* @brief Set full of alarm time in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
* contains alarm time value in full.
* @return None
**********************************************************************/
void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
RTCx->ALDOM = pFullTime->DOM & RTC_DOM_MASK;
RTCx->ALDOW = pFullTime->DOW & RTC_DOW_MASK;
RTCx->ALDOY = pFullTime->DOY & RTC_DOY_MASK;
RTCx->ALHOUR = pFullTime->HOUR & RTC_HOUR_MASK;
RTCx->ALMIN = pFullTime->MIN & RTC_MIN_MASK;
RTCx->ALSEC = pFullTime->SEC & RTC_SEC_MASK;
RTCx->ALMON = pFullTime->MONTH & RTC_MONTH_MASK;
RTCx->ALYEAR = pFullTime->YEAR & RTC_YEAR_MASK;
}
/*********************************************************************//**
* @brief Get full of alarm time in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
* will be stored alarm time in full.
* @return None
**********************************************************************/
void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
pFullTime->DOM = RTCx->ALDOM & RTC_DOM_MASK;
pFullTime->DOW = RTCx->ALDOW & RTC_DOW_MASK;
pFullTime->DOY = RTCx->ALDOY & RTC_DOY_MASK;
pFullTime->HOUR = RTCx->ALHOUR & RTC_HOUR_MASK;
pFullTime->MIN = RTCx->ALMIN & RTC_MIN_MASK;
pFullTime->SEC = RTCx->ALSEC & RTC_SEC_MASK;
pFullTime->MONTH = RTCx->ALMON & RTC_MONTH_MASK;
pFullTime->YEAR = RTCx->ALYEAR & RTC_YEAR_MASK;
}
/*********************************************************************//**
* @brief Check whether if specified Location interrupt in
* RTC peripheral is set or not
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] IntType Interrupt location type, should be:
* - RTC_INT_COUNTER_INCREASE: Counter Increment Interrupt
* block generated an interrupt.
* - RTC_INT_ALARM: Alarm generated an
* interrupt.
* @return New state of specified Location interrupt in RTC peripheral
* (SET or RESET)
**********************************************************************/
IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_INT(IntType));
return ((RTCx->ILR & IntType) ? SET : RESET);
}
/*********************************************************************//**
* @brief Clear specified Location interrupt pending in
* RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] IntType Interrupt location type, should be:
* - RTC_INT_COUNTER_INCREASE: Clear Counter Increment
* Interrupt pending.
* - RTC_INT_ALARM: Clear alarm interrupt pending
* @return None
**********************************************************************/
void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_INT(IntType));
RTCx->ILR |= IntType;
}
/*********************************************************************//**
* @brief Enable/Disable calibration counter in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] NewState New State of this function, should be:
* - ENABLE: The calibration counter is enabled and counting
* - DISABLE: The calibration counter is disabled and reset to zero
* @return None
**********************************************************************/
void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if (NewState == ENABLE)
{
RTCx->CCR &= (~RTC_CCR_CCALEN) & RTC_CCR_BITMASK;
}
else
{
RTCx->CCR |= RTC_CCR_CCALEN;
}
}
/*********************************************************************//**
* @brief Configures Calibration in RTC peripheral
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] CalibValue Calibration value, should be in range from
* 0 to 131,072
* @param[in] CalibDir Calibration Direction, should be:
* - RTC_CALIB_DIR_FORWARD: Forward calibration
* - RTC_CALIB_DIR_BACKWARD: Backward calibration
* @return None
**********************************************************************/
void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir)
{
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_CALIB_DIR(CalibDir));
CHECK_PARAM(CalibValue < RTC_CALIBRATION_MAX);
RTCx->CALIBRATION = ((CalibValue) & RTC_CALIBRATION_CALVAL_MASK) \
| ((CalibDir == RTC_CALIB_DIR_BACKWARD) ? RTC_CALIBRATION_LIBDIR : 0);
}
/*********************************************************************//**
* @brief Write value to General purpose registers
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Channel General purpose registers Channel number,
* should be in range from 0 to 4.
* @param[in] Value Value to write
* @return None
* Note: These General purpose registers can be used to store important
* information when the main power supply is off. The value in these
* registers is not affected by chip reset.
**********************************************************************/
void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value)
{
uint32_t *preg;
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));
preg = (uint32_t *)&RTCx->GPREG0;
preg += Channel;
*preg = Value;
}
/*********************************************************************//**
* @brief Read value from General purpose registers
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
* @param[in] Channel General purpose registers Channel number,
* should be in range from 0 to 4.
* @return Read Value
* Note: These General purpose registers can be used to store important
* information when the main power supply is off. The value in these
* registers is not affected by chip reset.
**********************************************************************/
uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel)
{
uint32_t *preg;
uint32_t value;
CHECK_PARAM(PARAM_RTCx(RTCx));
CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));
preg = (uint32_t *)&RTCx->GPREG0;
preg += Channel;
value = *preg;
return (value);
}
/**
* @}
*/
#endif /* _RTC */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,443 @@
/**********************************************************************
* $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 ------------------------------ */

View File

@ -0,0 +1,694 @@
/**********************************************************************
* $Id$ lpc17xx_ssp.c 2010-06-18
*//**
* @file lpc17xx_ssp.c
* @brief Contains all functions support for SSP firmware library on LPC17xx
* @version 3.0
* @date 18. June. 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 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
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup SSP_Public_Functions
* @{
*/
static void setSSPclock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock);
/*********************************************************************//**
* @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;
}
/**
* @}
*/
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup SSP_Public_Functions
* @{
*/
/********************************************************************//**
* @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_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 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));
}
/*****************************************************************************//**
* @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:
* - LPC_SSP0: SSP0 peripheral
* - LPC_SSP1: SSP1 peripheral
* @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:
* - LPC_SSP0: SSP0 peripheral
* - LPC_SSP1: SSP1 peripheral
* @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:
* - 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_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:
* - 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 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 SSP Read write data function
* @param[in] SSPx Pointer to SSP peripheral, should be
* - LPC_SSP0: SSP0 peripheral
* - LPC_SSP1: SSP1 peripheral
* @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;
uint8_t *wdata8;
uint16_t *rdata16;
uint16_t *wdata16;
uint32_t stat;
uint32_t tmp;
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;
if(SSP_GetDataSize(SSPx)>SSP_DATABIT_8)
dataword = 1;
else dataword = 0;
// 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){
while ((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, (*(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 (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 (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:
* - 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 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
* Note: We can enable/disable multi-interrupt type by OR multi value
**********************************************************************/
void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState)
{
CHECK_PARAM(PARAM_SSPx(SSPx));
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:
* - 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 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 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 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 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_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;
}
}
/**
* @}
*/
#endif /* _SSP */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,193 @@
/**********************************************************************
* $Id$ lpc17xx_systick.c 2010-05-21
*//**
* @file lpc17xx_systick.c
* @brief Contains all functions support for SYSTICK 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 SYSTICK
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_systick.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 _SYSTICK
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup SYSTICK_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initial System Tick with using internal CPU clock source
* @param[in] time time interval(ms)
* @return None
**********************************************************************/
void SYSTICK_InternalInit(uint32_t time)
{
uint32_t cclk;
float maxtime;
cclk = SystemCoreClock;
/* With internal CPU clock frequency for LPC17xx is 'SystemCoreClock'
* And limit 24 bit for RELOAD value
* So the maximum time can be set:
* 1/SystemCoreClock * (2^24) * 1000 (ms)
*/
//check time value is available or not
maxtime = (1<<24)/(SystemCoreClock / 1000) ;
if(time > maxtime)
//Error loop
while(1);
else
{
//Select CPU clock is System Tick clock source
SysTick->CTRL |= ST_CTRL_CLKSOURCE;
/* Set RELOAD value
* RELOAD = (SystemCoreClock/1000) * time - 1
* with time base is millisecond
*/
SysTick->LOAD = (cclk/1000)*time - 1;
}
}
/*********************************************************************//**
* @brief Initial System Tick with using external clock source
* @param[in] freq external clock frequency(Hz)
* @param[in] time time interval(ms)
* @return None
**********************************************************************/
void SYSTICK_ExternalInit(uint32_t freq, uint32_t time)
{
float maxtime;
/* With external clock frequency for LPC17xx is 'freq'
* And limit 24 bit for RELOAD value
* So the maximum time can be set:
* 1/freq * (2^24) * 1000 (ms)
*/
//check time value is available or not
maxtime = (1<<24)/(freq / 1000) ;
if (time>maxtime)
//Error Loop
while(1);
else
{
//Select external clock is System Tick clock source
SysTick->CTRL &= ~ ST_CTRL_CLKSOURCE;
/* Set RELOAD value
* RELOAD = (freq/1000) * time - 1
* with time base is millisecond
*/
maxtime = (freq/1000)*time - 1;
SysTick->LOAD = (freq/1000)*time - 1;
}
}
/*********************************************************************//**
* @brief Enable/disable System Tick counter
* @param[in] NewState System Tick counter status, should be:
* - ENABLE
* - DISABLE
* @return None
**********************************************************************/
void SYSTICK_Cmd(FunctionalState NewState)
{
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if(NewState == ENABLE)
//Enable System Tick counter
SysTick->CTRL |= ST_CTRL_ENABLE;
else
//Disable System Tick counter
SysTick->CTRL &= ~ST_CTRL_ENABLE;
}
/*********************************************************************//**
* @brief Enable/disable System Tick interrupt
* @param[in] NewState System Tick interrupt status, should be:
* - ENABLE
* - DISABLE
* @return None
**********************************************************************/
void SYSTICK_IntCmd(FunctionalState NewState)
{
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
if(NewState == ENABLE)
//Enable System Tick counter
SysTick->CTRL |= ST_CTRL_TICKINT;
else
//Disable System Tick counter
SysTick->CTRL &= ~ST_CTRL_TICKINT;
}
/*********************************************************************//**
* @brief Get current value of System Tick counter
* @param[in] None
* @return current value of System Tick counter
**********************************************************************/
uint32_t SYSTICK_GetCurrentValue(void)
{
return (SysTick->VAL);
}
/*********************************************************************//**
* @brief Clear Counter flag
* @param[in] None
* @return None
**********************************************************************/
void SYSTICK_ClearCounterFlag(void)
{
SysTick->CTRL &= ~ST_CTRL_COUNTFLAG;
}
/**
* @}
*/
#endif /* _SYSTICK */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

View File

@ -0,0 +1,609 @@
/**********************************************************************
* $Id$ lpc17xx_timer.c 2011-03-10
*//**
* @file lpc17xx_timer.c
* @brief Contains all functions support for Timer firmware library
* on LPC17xx
* @version 3.1
* @date 10. March. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, 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 TIM
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_timer.h"
#include "lpc17xx_clkpwr.h"
#include "lpc17xx_pinsel.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 _TIM
/* Private Functions ---------------------------------------------------------- */
static uint32_t getPClock (uint32_t timernum);
static uint32_t converUSecToVal (uint32_t timernum, uint32_t usec);
static uint32_t converPtrToTimeNum (LPC_TIM_TypeDef *TIMx);
/*********************************************************************//**
* @brief Get peripheral clock of each timer controller
* @param[in] timernum Timer number
* @return Peripheral clock of timer
**********************************************************************/
static uint32_t getPClock (uint32_t timernum)
{
uint32_t clkdlycnt;
switch (timernum)
{
case 0:
clkdlycnt = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_TIMER0);
break;
case 1:
clkdlycnt = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_TIMER1);
break;
case 2:
clkdlycnt = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_TIMER2);
break;
case 3:
clkdlycnt = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_TIMER3);
break;
}
return clkdlycnt;
}
/*********************************************************************//**
* @brief Convert a time to a timer count value
* @param[in] timernum Timer number
* @param[in] usec Time in microseconds
* @return The number of required clock ticks to give the time delay
**********************************************************************/
uint32_t converUSecToVal (uint32_t timernum, uint32_t usec)
{
uint64_t clkdlycnt;
// Get Pclock of timer
clkdlycnt = (uint64_t) getPClock(timernum);
clkdlycnt = (clkdlycnt * usec) / 1000000;
return (uint32_t) clkdlycnt;
}
/*********************************************************************//**
* @brief Convert a timer register pointer to a timer number
* @param[in] TIMx Pointer to LPC_TIM_TypeDef, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @return The timer number (0 to 3) or 0xFFFF FFFF if register pointer is bad
**********************************************************************/
uint32_t converPtrToTimeNum (LPC_TIM_TypeDef *TIMx)
{
uint32_t tnum = 0xFFFFFFFF;
if (TIMx == LPC_TIM0)
{
tnum = 0;
}
else if (TIMx == LPC_TIM1)
{
tnum = 1;
}
else if (TIMx == LPC_TIM2)
{
tnum = 2;
}
else if (TIMx == LPC_TIM3)
{
tnum = 3;
}
return tnum;
}
/* End of Private Functions ---------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup TIM_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Get Interrupt Status
* @param[in] TIMx Timer selection, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] IntFlag: interrupt type, should be:
* - TIM_MR0_INT: Interrupt for Match channel 0
* - TIM_MR1_INT: Interrupt for Match channel 1
* - TIM_MR2_INT: Interrupt for Match channel 2
* - TIM_MR3_INT: Interrupt for Match channel 3
* - TIM_CR0_INT: Interrupt for Capture channel 0
* - TIM_CR1_INT: Interrupt for Capture channel 1
* @return FlagStatus
* - SET : interrupt
* - RESET : no interrupt
**********************************************************************/
FlagStatus TIM_GetIntStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag)
{
uint8_t temp;
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
temp = (TIMx->IR)& TIM_IR_CLR(IntFlag);
if (temp)
return SET;
return RESET;
}
/*********************************************************************//**
* @brief Get Capture Interrupt Status
* @param[in] TIMx Timer selection, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] IntFlag: interrupt type, should be:
* - TIM_MR0_INT: Interrupt for Match channel 0
* - TIM_MR1_INT: Interrupt for Match channel 1
* - TIM_MR2_INT: Interrupt for Match channel 2
* - TIM_MR3_INT: Interrupt for Match channel 3
* - TIM_CR0_INT: Interrupt for Capture channel 0
* - TIM_CR1_INT: Interrupt for Capture channel 1
* @return FlagStatus
* - SET : interrupt
* - RESET : no interrupt
**********************************************************************/
FlagStatus TIM_GetIntCaptureStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag)
{
uint8_t temp;
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
temp = (TIMx->IR) & (1<<(4+IntFlag));
if(temp)
return SET;
return RESET;
}
/*********************************************************************//**
* @brief Clear Interrupt pending
* @param[in] TIMx Timer selection, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] IntFlag: interrupt type, should be:
* - TIM_MR0_INT: Interrupt for Match channel 0
* - TIM_MR1_INT: Interrupt for Match channel 1
* - TIM_MR2_INT: Interrupt for Match channel 2
* - TIM_MR3_INT: Interrupt for Match channel 3
* - TIM_CR0_INT: Interrupt for Capture channel 0
* - TIM_CR1_INT: Interrupt for Capture channel 1
* @return None
**********************************************************************/
void TIM_ClearIntPending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
TIMx->IR = TIM_IR_CLR(IntFlag);
}
/*********************************************************************//**
* @brief Clear Capture Interrupt pending
* @param[in] TIMx Timer selection, should be
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] IntFlag interrupt type, should be:
* - TIM_MR0_INT: Interrupt for Match channel 0
* - TIM_MR1_INT: Interrupt for Match channel 1
* - TIM_MR2_INT: Interrupt for Match channel 2
* - TIM_MR3_INT: Interrupt for Match channel 3
* - TIM_CR0_INT: Interrupt for Capture channel 0
* - TIM_CR1_INT: Interrupt for Capture channel 1
* @return None
**********************************************************************/
void TIM_ClearIntCapturePending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
TIMx->IR = (1<<(4+IntFlag));
}
/*********************************************************************//**
* @brief Configuration for Timer at initial time
* @param[in] TimerCounterMode timer counter mode, should be:
* - TIM_TIMER_MODE: Timer mode
* - TIM_COUNTER_RISING_MODE: Counter rising mode
* - TIM_COUNTER_FALLING_MODE: Counter falling mode
* - TIM_COUNTER_ANY_MODE:Counter on both edges
* @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type or
* TIM_COUNTERCFG_Type
* @return None
**********************************************************************/
void TIM_ConfigStructInit(TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct)
{
if (TimerCounterMode == TIM_TIMER_MODE )
{
TIM_TIMERCFG_Type * pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct;
pTimeCfg->PrescaleOption = TIM_PRESCALE_USVAL;
pTimeCfg->PrescaleValue = 1;
}
else
{
TIM_COUNTERCFG_Type * pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct;
pCounterCfg->CountInputSelect = TIM_COUNTER_INCAP0;
}
}
/*********************************************************************//**
* @brief Initial Timer/Counter device
* Set Clock frequency for Timer
* Set initial configuration for Timer
* @param[in] TIMx Timer selection, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] TimerCounterMode Timer counter mode, should be:
* - TIM_TIMER_MODE: Timer mode
* - TIM_COUNTER_RISING_MODE: Counter rising mode
* - TIM_COUNTER_FALLING_MODE: Counter falling mode
* - TIM_COUNTER_ANY_MODE:Counter on both edges
* @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type
* that contains the configuration information for the
* specified Timer peripheral.
* @return None
**********************************************************************/
void TIM_Init(LPC_TIM_TypeDef *TIMx, TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct)
{
TIM_TIMERCFG_Type *pTimeCfg;
TIM_COUNTERCFG_Type *pCounterCfg;
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_MODE_OPT(TimerCounterMode));
//set power
if (TIMx== LPC_TIM0)
{
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM0, ENABLE);
//PCLK_Timer0 = CCLK/4
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER0, CLKPWR_PCLKSEL_CCLK_DIV_4);
}
else if (TIMx== LPC_TIM1)
{
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM1, ENABLE);
//PCLK_Timer1 = CCLK/4
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER1, CLKPWR_PCLKSEL_CCLK_DIV_4);
}
else if (TIMx== LPC_TIM2)
{
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, ENABLE);
//PCLK_Timer2= CCLK/4
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER2, CLKPWR_PCLKSEL_CCLK_DIV_4);
}
else if (TIMx== LPC_TIM3)
{
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM3, ENABLE);
//PCLK_Timer3= CCLK/4
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER3, CLKPWR_PCLKSEL_CCLK_DIV_4);
}
TIMx->CCR &= ~TIM_CTCR_MODE_MASK;
TIMx->CCR |= TIM_TIMER_MODE;
TIMx->TC =0;
TIMx->PC =0;
TIMx->PR =0;
TIMx->TCR |= (1<<1); //Reset Counter
TIMx->TCR &= ~(1<<1); //release reset
if (TimerCounterMode == TIM_TIMER_MODE )
{
pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct;
if (pTimeCfg->PrescaleOption == TIM_PRESCALE_TICKVAL)
{
TIMx->PR = pTimeCfg->PrescaleValue -1 ;
}
else
{
TIMx->PR = converUSecToVal (converPtrToTimeNum(TIMx),pTimeCfg->PrescaleValue)-1;
}
}
else
{
pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct;
TIMx->CCR &= ~TIM_CTCR_INPUT_MASK;
if (pCounterCfg->CountInputSelect == TIM_COUNTER_INCAP1)
TIMx->CCR |= _BIT(2);
}
// Clear interrupt pending
TIMx->IR = 0xFFFFFFFF;
}
/*********************************************************************//**
* @brief Close Timer/Counter device
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @return None
**********************************************************************/
void TIM_DeInit (LPC_TIM_TypeDef *TIMx)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
// Disable timer/counter
TIMx->TCR = 0x00;
// Disable power
if (TIMx== LPC_TIM0)
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM0, DISABLE);
else if (TIMx== LPC_TIM1)
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM1, DISABLE);
else if (TIMx== LPC_TIM2)
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, DISABLE);
else if (TIMx== LPC_TIM3)
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, DISABLE);
}
/*********************************************************************//**
* @brief Start/Stop Timer/Counter device
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] NewState
* - ENABLE : set timer enable
* - DISABLE : disable timer
* @return None
**********************************************************************/
void TIM_Cmd(LPC_TIM_TypeDef *TIMx, FunctionalState NewState)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
if (NewState == ENABLE)
{
TIMx->TCR |= TIM_ENABLE;
}
else
{
TIMx->TCR &= ~TIM_ENABLE;
}
}
/*********************************************************************//**
* @brief Reset Timer/Counter device,
* Make TC and PC are synchronously reset on the next
* positive edge of PCLK
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @return None
**********************************************************************/
void TIM_ResetCounter(LPC_TIM_TypeDef *TIMx)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
TIMx->TCR |= TIM_RESET;
TIMx->TCR &= ~TIM_RESET;
}
/*********************************************************************//**
* @brief Configuration for Match register
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] TIM_MatchConfigStruct Pointer to TIM_MATCHCFG_Type
* - MatchChannel : choose channel 0 or 1
* - IntOnMatch : if SET, interrupt will be generated when MRxx match
* the value in TC
* - StopOnMatch : if SET, TC and PC will be stopped whenM Rxx match
* the value in TC
* - ResetOnMatch : if SET, Reset on MR0 when MRxx match
* the value in TC
* -ExtMatchOutputType: Select output for external match
* + 0: Do nothing for external output pin if match
* + 1: Force external output pin to low if match
* + 2: Force external output pin to high if match
* + 3: Toggle external output pin if match
* MatchValue: Set the value to be compared with TC value
* @return None
**********************************************************************/
void TIM_ConfigMatch(LPC_TIM_TypeDef *TIMx, TIM_MATCHCFG_Type *TIM_MatchConfigStruct)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_EXTMATCH_OPT(TIM_MatchConfigStruct->ExtMatchOutputType));
switch(TIM_MatchConfigStruct->MatchChannel)
{
case 0:
TIMx->MR0 = TIM_MatchConfigStruct->MatchValue;
break;
case 1:
TIMx->MR1 = TIM_MatchConfigStruct->MatchValue;
break;
case 2:
TIMx->MR2 = TIM_MatchConfigStruct->MatchValue;
break;
case 3:
TIMx->MR3 = TIM_MatchConfigStruct->MatchValue;
break;
default:
//Error match value
//Error loop
while(1);
}
//interrupt on MRn
TIMx->MCR &=~TIM_MCR_CHANNEL_MASKBIT(TIM_MatchConfigStruct->MatchChannel);
if (TIM_MatchConfigStruct->IntOnMatch)
TIMx->MCR |= TIM_INT_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
//reset on MRn
if (TIM_MatchConfigStruct->ResetOnMatch)
TIMx->MCR |= TIM_RESET_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
//stop on MRn
if (TIM_MatchConfigStruct->StopOnMatch)
TIMx->MCR |= TIM_STOP_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
// match output type
TIMx->EMR &= ~TIM_EM_MASK(TIM_MatchConfigStruct->MatchChannel);
TIMx->EMR |= TIM_EM_SET(TIM_MatchConfigStruct->MatchChannel,TIM_MatchConfigStruct->ExtMatchOutputType);
}
/*********************************************************************//**
* @brief Update Match value
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] MatchChannel Match channel, should be: 0..3
* @param[in] MatchValue updated match value
* @return None
**********************************************************************/
void TIM_UpdateMatchValue(LPC_TIM_TypeDef *TIMx,uint8_t MatchChannel, uint32_t MatchValue)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
switch(MatchChannel)
{
case 0:
TIMx->MR0 = MatchValue;
break;
case 1:
TIMx->MR1 = MatchValue;
break;
case 2:
TIMx->MR2 = MatchValue;
break;
case 3:
TIMx->MR3 = MatchValue;
break;
default:
//Error Loop
while(1);
}
}
/*********************************************************************//**
* @brief Configuration for Capture register
* @param[in] TIMx Pointer to timer device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* - CaptureChannel: set the channel to capture data
* - RisingEdge : if SET, Capture at rising edge
* - FallingEdge : if SET, Capture at falling edge
* - IntOnCaption : if SET, Capture generate interrupt
* @param[in] TIM_CaptureConfigStruct Pointer to TIM_CAPTURECFG_Type
* @return None
**********************************************************************/
void TIM_ConfigCapture(LPC_TIM_TypeDef *TIMx, TIM_CAPTURECFG_Type *TIM_CaptureConfigStruct)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
TIMx->CCR &= ~TIM_CCR_CHANNEL_MASKBIT(TIM_CaptureConfigStruct->CaptureChannel);
if (TIM_CaptureConfigStruct->RisingEdge)
TIMx->CCR |= TIM_CAP_RISING(TIM_CaptureConfigStruct->CaptureChannel);
if (TIM_CaptureConfigStruct->FallingEdge)
TIMx->CCR |= TIM_CAP_FALLING(TIM_CaptureConfigStruct->CaptureChannel);
if (TIM_CaptureConfigStruct->IntOnCaption)
TIMx->CCR |= TIM_INT_ON_CAP(TIM_CaptureConfigStruct->CaptureChannel);
}
/*********************************************************************//**
* @brief Read value of capture register in timer/counter device
* @param[in] TIMx Pointer to timer/counter device, should be:
* - LPC_TIM0: TIMER0 peripheral
* - LPC_TIM1: TIMER1 peripheral
* - LPC_TIM2: TIMER2 peripheral
* - LPC_TIM3: TIMER3 peripheral
* @param[in] CaptureChannel: capture channel number, should be:
* - TIM_COUNTER_INCAP0: CAPn.0 input pin for TIMERn
* - TIM_COUNTER_INCAP1: CAPn.1 input pin for TIMERn
* @return Value of capture register
**********************************************************************/
uint32_t TIM_GetCaptureValue(LPC_TIM_TypeDef *TIMx, TIM_COUNTER_INPUT_OPT CaptureChannel)
{
CHECK_PARAM(PARAM_TIMx(TIMx));
CHECK_PARAM(PARAM_TIM_COUNTER_INPUT_OPT(CaptureChannel));
if(CaptureChannel==0)
return TIMx->CR0;
else
return TIMx->CR1;
}
/**
* @}
*/
#endif /* _TIMER */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,274 @@
/**********************************************************************
* $Id$ lpc17xx_wdt.c 2010-05-21
*//**
* @file lpc17xx_wdt.c
* @brief Contains all functions support for WDT 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 WDT
* @{
*/
/* Includes ------------------------------------------------------------------- */
#include "lpc17xx_wdt.h"
#include "lpc17xx_clkpwr.h"
#include "lpc17xx_pinsel.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 _WDT
/* Private Functions ---------------------------------------------------------- */
static uint8_t WDT_SetTimeOut (uint8_t clk_source, uint32_t timeout);
/********************************************************************//**
* @brief Set WDT time out value and WDT mode
* @param[in] clk_source select Clock source for WDT device
* @param[in] timeout value of time-out for WDT (us)
* @return None
*********************************************************************/
static uint8_t WDT_SetTimeOut (uint8_t clk_source, uint32_t timeout)
{
uint32_t pclk_wdt = 0;
uint32_t tempval = 0;
switch ((WDT_CLK_OPT) clk_source)
{
case WDT_CLKSRC_IRC:
pclk_wdt = 4000000;
// Calculate TC in WDT
tempval = ((((uint64_t)pclk_wdt * (uint64_t)timeout / 4) / (uint64_t)WDT_US_INDEX));
// Check if it valid
if (tempval >= WDT_TIMEOUT_MIN)
{
LPC_WDT->WDTC = tempval;
return SUCCESS;
}
break;
case WDT_CLKSRC_PCLK:
// Get WDT clock with CCLK divider = 4
pclk_wdt = SystemCoreClock / 4;
// Calculate TC in WDT
tempval = ((((uint64_t)pclk_wdt * (uint64_t)timeout / 4) / (uint64_t)WDT_US_INDEX));
if (tempval >= WDT_TIMEOUT_MIN)
{
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_4);
LPC_WDT->WDTC = (uint32_t) tempval;
return SUCCESS;
}
// Get WDT clock with CCLK divider = 2
pclk_wdt = SystemCoreClock / 2;
// Calculate TC in WDT
tempval = ((((uint64_t)pclk_wdt * (uint64_t)timeout / 4) / (uint64_t)WDT_US_INDEX));
if (tempval >= WDT_TIMEOUT_MIN)
{
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_2);
LPC_WDT->WDTC = (uint32_t) tempval;
return SUCCESS;
}
// Get WDT clock with CCLK divider = 1
pclk_wdt = SystemCoreClock;
// Calculate TC in WDT
tempval = ((((uint64_t)pclk_wdt * (uint64_t)timeout / 4) / (uint64_t)WDT_US_INDEX));
if (tempval >= WDT_TIMEOUT_MIN)
{
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_1);
LPC_WDT->WDTC = (uint32_t) tempval;
return SUCCESS;
}
break ;
case WDT_CLKSRC_RTC:
pclk_wdt = 32768;
// Calculate TC in WDT
tempval = ((((uint64_t)pclk_wdt * (uint64_t)timeout / 4) / (uint64_t)WDT_US_INDEX));
// Check if it valid
if (tempval >= WDT_TIMEOUT_MIN)
{
LPC_WDT->WDTC = (uint32_t) tempval;
return SUCCESS;
}
break;
// Error parameter
default:
break;
}
return ERROR;
}
/* End of Private Functions --------------------------------------------------- */
/* Public Functions ----------------------------------------------------------- */
/** @addtogroup WDT_Public_Functions
* @{
*/
/*********************************************************************//**
* @brief Initial for Watchdog function
* Clock source = RTC ,
* @param[in] ClkSrc Select clock source, should be:
* - WDT_CLKSRC_IRC: Clock source from Internal RC oscillator
* - WDT_CLKSRC_PCLK: Selects the APB peripheral clock (PCLK)
* - WDT_CLKSRC_RTC: Selects the RTC oscillator
* @param[in] WDTMode WDT mode, should be:
* - WDT_MODE_INT_ONLY: Use WDT to generate interrupt only
* - WDT_MODE_RESET: Use WDT to generate interrupt and reset MCU
* @return None
**********************************************************************/
void WDT_Init (WDT_CLK_OPT ClkSrc, WDT_MODE_OPT WDTMode)
{
CHECK_PARAM(PARAM_WDT_CLK_OPT(ClkSrc));
CHECK_PARAM(PARAM_WDT_MODE_OPT(WDTMode));
CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_WDT, CLKPWR_PCLKSEL_CCLK_DIV_4);
//Set clock source
LPC_WDT->WDCLKSEL &= ~WDT_WDCLKSEL_MASK;
LPC_WDT->WDCLKSEL |= ClkSrc;
//Set WDT mode
if (WDTMode == WDT_MODE_RESET){
LPC_WDT->WDMOD |= WDT_WDMOD(WDTMode);
}
}
/*********************************************************************//**
* @brief Start WDT activity with given timeout value
* @param[in] TimeOut WDT reset after timeout if it is not feed
* @return None
**********************************************************************/
void WDT_Start(uint32_t TimeOut)
{
uint32_t ClkSrc;
ClkSrc = LPC_WDT->WDCLKSEL;
ClkSrc &=WDT_WDCLKSEL_MASK;
WDT_SetTimeOut(ClkSrc,TimeOut);
//enable watchdog
LPC_WDT->WDMOD |= WDT_WDMOD_WDEN;
WDT_Feed();
}
/********************************************************************//**
* @brief Read WDT Time out flag
* @param[in] None
* @return Time out flag status of WDT
*********************************************************************/
FlagStatus WDT_ReadTimeOutFlag (void)
{
return ((FlagStatus)((LPC_WDT->WDMOD & WDT_WDMOD_WDTOF) >>2));
}
/********************************************************************//**
* @brief Clear WDT Time out flag
* @param[in] None
* @return None
*********************************************************************/
void WDT_ClrTimeOutFlag (void)
{
LPC_WDT->WDMOD &=~WDT_WDMOD_WDTOF;
}
/********************************************************************//**
* @brief Update WDT timeout value and feed
* @param[in] TimeOut TimeOut value to be updated
* @return None
*********************************************************************/
void WDT_UpdateTimeOut ( uint32_t TimeOut)
{
uint32_t ClkSrc;
ClkSrc = LPC_WDT->WDCLKSEL;
ClkSrc &=WDT_WDCLKSEL_MASK;
WDT_SetTimeOut(ClkSrc,TimeOut);
WDT_Feed();
}
/********************************************************************//**
* @brief After set WDTEN, call this function to start Watchdog
* or reload the Watchdog timer
* @param[in] None
*
* @return None
*********************************************************************/
void WDT_Feed (void)
{
// Disable irq interrupt
__disable_irq();
LPC_WDT->WDFEED = 0xAA;
LPC_WDT->WDFEED = 0x55;
// Then enable irq interrupt
__enable_irq();
}
/********************************************************************//**
* @brief Get the current value of WDT
* @param[in] None
* @return current value of WDT
*********************************************************************/
uint32_t WDT_GetCurrentCount(void)
{
return LPC_WDT->WDTV;
}
/**
* @}
*/
#endif /* _WDT */
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */