Date: March 20, 2011 This library is created from "LPC17xx CMSIS-Compliant Standard Peripheral Firmware Driver Library (GNU, Keil, IAR) (Jan 28, 2011)", available from NXP's website, under "All microcontrollers support documents" [[http://ics.nxp.com/support/documents/microcontrollers/?type=software]] You will need to follow [[/projects/libraries/svn/mbed/trunk/LPC1768/LPC17xx.h]] while using this library Examples provided here [[/users/frank26080115/programs/LPC1700CMSIS_Examples/]] The beautiful thing is that NXP does not place copyright protection on any of the files in here Only a few modifications are made to make it compile with the mbed online compiler, I fixed some warnings as well. This is untested as of March 20, 2011 Forum post about this library: [[/forum/mbed/topic/2030/]]
Revision 0:84d7747641aa, committed 2011-03-20
- Comitter:
- frank26080115
- Date:
- Sun Mar 20 18:45:15 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 84d7747641aa debug_frmwrk.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debug_frmwrk.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,305 @@ +/***********************************************************************//** + * @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 + *---------------------------------------------------------------------------- + * 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. + **********************************************************************/ + +#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 */
diff -r 000000000000 -r 84d7747641aa debug_frmwrk.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debug_frmwrk.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,69 @@ +/***********************************************************************//** + * @file debug_frmwrk.h + * @brief Contains some utilities that used for debugging through UART + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + *---------------------------------------------------------------------------- + * 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. + **********************************************************************/ + +#ifndef DEBUG_FRMWRK_H_ +#define DEBUG_FRMWRK_H_ + +//#include <stdarg.h> +#include "lpc17xx_uart.h" + +#define USED_UART_DEBUG_PORT 0 + +#if (USED_UART_DEBUG_PORT==0) +#define DEBUG_UART_PORT LPC_UART0 +#elif (USED_UART_DEBUG_PORT==1) +#define DEBUG_UART_PORT LPC_UART1 +#endif + +#define _DBG(x) _db_msg(DEBUG_UART_PORT, x) +#define _DBG_(x) _db_msg_(DEBUG_UART_PORT, x) +#define _DBC(x) _db_char(DEBUG_UART_PORT, x) +#define _DBD(x) _db_dec(DEBUG_UART_PORT, x) +#define _DBD16(x) _db_dec_16(DEBUG_UART_PORT, x) +#define _DBD32(x) _db_dec_32(DEBUG_UART_PORT, x) +#define _DBH(x) _db_hex(DEBUG_UART_PORT, x) +#define _DBH16(x) _db_hex_16(DEBUG_UART_PORT, x) +#define _DBH32(x) _db_hex_32(DEBUG_UART_PORT, x) +#define _DG _db_get_char(DEBUG_UART_PORT) +//void _printf (const char *format, ...); + +extern void (*_db_msg)(LPC_UART_TypeDef *UARTx, const void *s); +extern void (*_db_msg_)(LPC_UART_TypeDef *UARTx, const void *s); +extern void (*_db_char)(LPC_UART_TypeDef *UARTx, uint8_t ch); +extern void (*_db_dec)(LPC_UART_TypeDef *UARTx, uint8_t decn); +extern void (*_db_dec_16)(LPC_UART_TypeDef *UARTx, uint16_t decn); +extern void (*_db_dec_32)(LPC_UART_TypeDef *UARTx, uint32_t decn); +extern void (*_db_hex)(LPC_UART_TypeDef *UARTx, uint8_t hexn); +extern void (*_db_hex_16)(LPC_UART_TypeDef *UARTx, uint16_t hexn); +extern void (*_db_hex_32)(LPC_UART_TypeDef *UARTx, uint32_t hexn); +extern uint8_t (*_db_get_char)(LPC_UART_TypeDef *UARTx); + +void UARTPutChar (LPC_UART_TypeDef *UARTx, uint8_t ch); +void UARTPuts(LPC_UART_TypeDef *UARTx, const void *str); +void UARTPuts_(LPC_UART_TypeDef *UARTx, const void *str); +void UARTPutDec(LPC_UART_TypeDef *UARTx, uint8_t decnum); +void UARTPutDec16(LPC_UART_TypeDef *UARTx, uint16_t decnum); +void UARTPutDec32(LPC_UART_TypeDef *UARTx, uint32_t decnum); +void UARTPutHex (LPC_UART_TypeDef *UARTx, uint8_t hexnum); +void UARTPutHex16 (LPC_UART_TypeDef *UARTx, uint16_t hexnum); +void UARTPutHex32 (LPC_UART_TypeDef *UARTx, uint32_t hexnum); +uint8_t UARTGetChar (LPC_UART_TypeDef *UARTx); +void debug_frmwrk_init(void); + +#endif /* DEBUG_FRMWRK_H_ */
diff -r 000000000000 -r 84d7747641aa lpc17xx.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,1 @@ +#include "mbed.h" \ No newline at end of file
diff -r 000000000000 -r 84d7747641aa lpc17xx_adc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_adc.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,340 @@ +/***********************************************************************//** + * @file lpc17xx_adc.c + * @brief Contains all functions support for ADC firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 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 + temp = 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 = (temp /(rate * 65)) - 1; + 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)); + + // 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 { + 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_adc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_adc.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,288 @@ +/***********************************************************************//** + * @file lpc17xx_adc.h + * @brief Contains all macro definitions and function prototypes + * support for ADC firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup ADC ADC + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_ADC_H_ +#define LPC17XX_ADC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include <LPC17xx.h> +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private macros ------------------------------------------------------------- */ +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ + +/* -------------------------- BIT DEFINITIONS ----------------------------------- */ +/*********************************************************************//** + * Macro defines for ADC control register + **********************************************************************/ +/** Selects which of the AD0.0:7 pins is (are) to be sampled and converted */ +#define ADC_CR_CH_SEL(n) ((1UL << n)) +/** The APB clock (PCLK) is divided by (this value plus one) +* to produce the clock for the A/D */ +#define ADC_CR_CLKDIV(n) ((n<<8)) +/** Repeated conversions A/D enable bit */ +#define ADC_CR_BURST ((1UL<<16)) +/** ADC convert in power down mode */ +#define ADC_CR_PDN ((1UL<<21)) +/** Start mask bits */ +#define ADC_CR_START_MASK ((7UL<<24)) +/** Select Start Mode */ +#define ADC_CR_START_MODE_SEL(SEL) ((SEL<<24)) +/** Start conversion now */ +#define ADC_CR_START_NOW ((1UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on P2.10/EINT0 */ +#define ADC_CR_START_EINT0 ((2UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on P1.27/CAP0.1 */ +#define ADC_CR_START_CAP01 ((3UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on MAT0.1 */ +#define ADC_CR_START_MAT01 ((4UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on MAT0.3 */ +#define ADC_CR_START_MAT03 ((5UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on MAT1.0 */ +#define ADC_CR_START_MAT10 ((6UL<<24)) +/** Start conversion when the edge selected by bit 27 occurs on MAT1.1 */ +#define ADC_CR_START_MAT11 ((7UL<<24)) +/** Start conversion on a falling edge on the selected CAP/MAT signal */ +#define ADC_CR_EDGE ((1UL<<27)) + +/*********************************************************************//** + * Macro defines for ADC Global Data register + **********************************************************************/ +/** When DONE is 1, this field contains result value of ADC conversion */ +#define ADC_GDR_RESULT(n) (((n>>4)&0xFFF)) +/** These bits contain the channel from which the LS bits were converted */ +#define ADC_GDR_CH(n) (((n>>24)&0x7)) +/** This bit is 1 in burst mode if the results of one or + * more conversions was (were) lost */ +#define ADC_GDR_OVERRUN_FLAG ((1UL<<30)) +/** This bit is set to 1 when an A/D conversion completes */ +#define ADC_GDR_DONE_FLAG ((1UL<<31)) + +/** This bits is used to mask for Channel */ +#define ADC_GDR_CH_MASK ((7UL<<24)) +/*********************************************************************//** + * Macro defines for ADC Interrupt register + **********************************************************************/ +/** These bits allow control over which A/D channels generate + * interrupts for conversion completion */ +#define ADC_INTEN_CH(n) ((1UL<<n)) +/** When 1, enables the global DONE flag in ADDR to generate an interrupt */ +#define ADC_INTEN_GLOBAL ((1UL<<8)) + +/*********************************************************************//** + * Macro defines for ADC Data register + **********************************************************************/ +/** When DONE is 1, this field contains result value of ADC conversion */ +#define ADC_DR_RESULT(n) (((n>>4)&0xFFF)) +/** These bits mirror the OVERRRUN status flags that appear in the + * result register for each A/D channel */ +#define ADC_DR_OVERRUN_FLAG ((1UL<<30)) +/** This bit is set to 1 when an A/D conversion completes. It is cleared + * when this register is read */ +#define ADC_DR_DONE_FLAG ((1UL<<31)) + +/*********************************************************************//** + * Macro defines for ADC Status register +**********************************************************************/ +/** These bits mirror the DONE status flags that appear in the result + * register for each A/D channel */ +#define ADC_STAT_CH_DONE_FLAG(n) ((n&0xFF)) +/** These bits mirror the OVERRRUN status flags that appear in the + * result register for each A/D channel */ +#define ADC_STAT_CH_OVERRUN_FLAG(n) (((n>>8)&0xFF)) +/** This bit is the A/D interrupt flag */ +#define ADC_STAT_INT_FLAG ((1UL<<16)) + +/*********************************************************************//** + * Macro defines for ADC Trim register +**********************************************************************/ +/** Offset trim bits for ADC operation */ +#define ADC_ADCOFFS(n) (((n&0xF)<<4)) +/** Written to boot code*/ +#define ADC_TRIM(n) (((n&0xF)<<8)) + +/* ------------------- CHECK PARAM DEFINITIONS ------------------------- */ +/** Check ADC parameter */ +#define PARAM_ADCx(n) (((uint32_t *)n)==((uint32_t *)LPC_ADC)) + +/** Check ADC state parameter */ +#define PARAM_ADC_START_ON_EDGE_OPT(OPT) ((OPT == ADC_START_ON_RISING)||(OPT == ADC_START_ON_FALLING)) + +/** Check ADC state parameter */ +#define PARAM_ADC_DATA_STATUS(OPT) ((OPT== ADC_DATA_BURST)||(OPT== ADC_DATA_DONE)) + +/** Check ADC rate parameter */ +#define PARAM_ADC_RATE(rate) ((rate>0)&&(rate<=200000)) + +/** Check ADC channel selection parameter */ +#define PARAM_ADC_CHANNEL_SELECTION(SEL) ((SEL == ADC_CHANNEL_0)||(ADC_CHANNEL_1)\ +||(SEL == ADC_CHANNEL_2)|(ADC_CHANNEL_3)\ +||(SEL == ADC_CHANNEL_4)||(ADC_CHANNEL_5)\ +||(SEL == ADC_CHANNEL_6)||(ADC_CHANNEL_7)) + +/** Check ADC start option parameter */ +#define PARAM_ADC_START_OPT(OPT) ((OPT == ADC_START_CONTINUOUS)||(OPT == ADC_START_NOW)\ +||(OPT == ADC_START_ON_EINT0)||(OPT == ADC_START_ON_CAP01)\ +||(OPT == ADC_START_ON_MAT01)||(OPT == ADC_START_ON_MAT03)\ +||(OPT == ADC_START_ON_MAT10)||(OPT == ADC_START_ON_MAT11)) + +/** Check ADC interrupt type parameter */ +#define PARAM_ADC_TYPE_INT_OPT(OPT) ((OPT == ADC_ADINTEN0)||(OPT == ADC_ADINTEN1)\ +||(OPT == ADC_ADINTEN2)||(OPT == ADC_ADINTEN3)\ +||(OPT == ADC_ADINTEN4)||(OPT == ADC_ADINTEN5)\ +||(OPT == ADC_ADINTEN6)||(OPT == ADC_ADINTEN7)\ +||(OPT == ADC_ADGINTEN)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup ADC_Public_Types ADC Public Types + * @{ + */ + +/*********************************************************************//** + * @brief ADC enumeration + **********************************************************************/ +/** @brief Channel Selection */ +typedef enum +{ + ADC_CHANNEL_0 = 0, /*!< Channel 0 */ + ADC_CHANNEL_1, /*!< Channel 1 */ + ADC_CHANNEL_2, /*!< Channel 2 */ + ADC_CHANNEL_3, /*!< Channel 3 */ + ADC_CHANNEL_4, /*!< Channel 4 */ + ADC_CHANNEL_5, /*!< Channel 5 */ + ADC_CHANNEL_6, /*!< Channel 6 */ + ADC_CHANNEL_7 /*!< Channel 7 */ +}ADC_CHANNEL_SELECTION; + +/** @brief Type of start option */ +typedef enum +{ + ADC_START_CONTINUOUS =0, /*!< Continuous mode */ + ADC_START_NOW, /*!< Start conversion now */ + ADC_START_ON_EINT0, /*!< Start conversion when the edge selected + * by bit 27 occurs on P2.10/EINT0 */ + ADC_START_ON_CAP01, /*!< Start conversion when the edge selected + * by bit 27 occurs on P1.27/CAP0.1 */ + ADC_START_ON_MAT01, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT0.1 */ + ADC_START_ON_MAT03, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT0.3 */ + ADC_START_ON_MAT10, /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT1.0 */ + ADC_START_ON_MAT11 /*!< Start conversion when the edge selected + * by bit 27 occurs on MAT1.1 */ +} ADC_START_OPT; + + +/** @brief Type of edge when start conversion on the selected CAP/MAT signal */ +typedef enum +{ + ADC_START_ON_RISING = 0, /*!< Start conversion on a rising edge + *on the selected CAP/MAT signal */ + ADC_START_ON_FALLING /*!< Start conversion on a falling edge + *on the selected CAP/MAT signal */ +} ADC_START_ON_EDGE_OPT; + +/** @brief* ADC type interrupt enum */ +typedef enum +{ + ADC_ADINTEN0 = 0, /*!< Interrupt channel 0 */ + ADC_ADINTEN1, /*!< Interrupt channel 1 */ + ADC_ADINTEN2, /*!< Interrupt channel 2 */ + ADC_ADINTEN3, /*!< Interrupt channel 3 */ + ADC_ADINTEN4, /*!< Interrupt channel 4 */ + ADC_ADINTEN5, /*!< Interrupt channel 5 */ + ADC_ADINTEN6, /*!< Interrupt channel 6 */ + ADC_ADINTEN7, /*!< Interrupt channel 7 */ + ADC_ADGINTEN /*!< Individual channel/global flag done generate an interrupt */ +}ADC_TYPE_INT_OPT; + +/** @brief ADC Data status */ +typedef enum +{ + ADC_DATA_BURST = 0, /*Burst bit*/ + ADC_DATA_DONE /*Done bit*/ +}ADC_DATA_STATUS; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup ADC_Public_Functions ADC Public Functions + * @{ + */ +/* Init/DeInit ADC peripheral ----------------*/ +void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t rate); +void ADC_DeInit(LPC_ADC_TypeDef *ADCx); + +/* Enable/Disable ADC functions --------------*/ +void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState); +void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState); +void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode); +void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState); + +/* Configure ADC functions -------------------*/ +void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption); +void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState); + +/* Get ADC information functions -------------------*/ +uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel); +FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType); +uint32_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx); +FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC17XX_ADC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_can.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_can.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,1896 @@ +/***********************************************************************//** + * @file lpc17xx_can.c + * @brief Contains all functions support for CAN firmware library on LPC17xx + * @version 3.2 + * @date 06. Dec. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup CAN + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_can.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 _CAN + +/* Private Variables ---------------------------------------------------------- */ +/** @defgroup CAN_Private_Variables CAN Private Variables + * @{ + */ + +FunctionalState FULLCAN_ENABLE; + + +/* Counts number of filters (CAN message objects) used */ +uint16_t CANAF_FullCAN_cnt = 0; +uint16_t CANAF_std_cnt = 0; +uint16_t CANAF_gstd_cnt = 0; +uint16_t CANAF_ext_cnt = 0; +uint16_t CANAF_gext_cnt = 0; + +/* End of Private Variables ----------------------------------------------------*/ +/** + * @} + */ + +/* Private Variables ---------------------------------------------------------- */ +static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate); + +/*********************************************************************//** + * @brief Setting CAN baud rate (bps) + * @param[in] CANx point to LPC_CAN_TypeDef object, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] baudrate: is the baud rate value will be set + * @return None + ***********************************************************************/ +static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate) +{ + uint32_t result = 0; + uint8_t NT, TSEG1 = 0, TSEG2 = 0, BRFail; + uint32_t CANPclk = 0; + uint32_t BRP = 0; + CHECK_PARAM(PARAM_CANx(CANx)); + + if (CANx == LPC_CAN1) + { + CANPclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_CAN1); + } + else + { + CANPclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_CAN2); + } + result = CANPclk / baudrate; + /* Calculate suitable nominal time value + * NT (nominal time) = (TSEG1 + TSEG2 + 3) + * NT <= 24 + * TSEG1 >= 2*TSEG2 + */ + BRFail = 1; + for(NT=24;NT>0;NT=NT-2) + { + if ((result%NT)==0) + { + BRP = result / NT - 1; + NT--; + TSEG2 = (NT/3) - 1; + TSEG1 = NT -(NT/3) - 1; + BRFail = 0; + break; + } + } + if(BRFail) + while(1); // Failed to calculate exact CAN baud rate + /* Enter reset mode */ + CANx->MOD = 0x01; + /* Set bit timing + * Default: SAM = 0x00; + * SJW = 0x03; + */ + CANx->BTR = (TSEG2<<20)|(TSEG1<<16)|(3<<14)|BRP; + /* Return to normal operating */ + CANx->MOD = 0; +} +/* End of Private Functions ----------------------------------------------------*/ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup CAN_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initialize CAN peripheral with given baudrate + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] baudrate: the value of CAN baudrate will be set (bps) + * @return None + *********************************************************************/ +void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate) +{ + uint16_t i; + CHECK_PARAM(PARAM_CANx(CANx)); + + if(CANx == LPC_CAN1) + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE); + /* Set clock divide for CAN1 */ + } + else + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE); + /* Set clock divide for CAN2 */ + } + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_CAN1, CLKPWR_PCLKSEL_CCLK_DIV_2); + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_CAN2, CLKPWR_PCLKSEL_CCLK_DIV_2); + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_ACF, CLKPWR_PCLKSEL_CCLK_DIV_2); + + CANx->MOD = 1; // Enter Reset Mode + CANx->IER = 0; // Disable All CAN Interrupts + CANx->GSR = 0; + /* Request command to release Rx, Tx buffer and clear data overrun */ + //CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO; + CANx->CMR = (1<<1)|(1<<2)|(1<<3); + /* Read to clear interrupt pending in interrupt capture register */ + volatile uint32_t temp = CANx->ICR; + CANx->MOD = 0;// Return Normal operating + + //Reset CANAF value + LPC_CANAF->AFMR = 0x01; + + //clear ALUT RAM + for (i = 0; i < 512; i++) { + LPC_CANAF_RAM->mask[i] = 0x00; + } + + LPC_CANAF->SFF_sa = 0x00; + LPC_CANAF->SFF_GRP_sa = 0x00; + LPC_CANAF->EFF_sa = 0x00; + LPC_CANAF->EFF_GRP_sa = 0x00; + LPC_CANAF->ENDofTable = 0x00; + + LPC_CANAF->AFMR = 0x00; + /* Set baudrate */ + can_SetBaudrate (CANx, baudrate); +} + +/********************************************************************//** + * @brief CAN deInit + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @return None + *********************************************************************/ +void CAN_DeInit(LPC_CAN_TypeDef *CANx) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + + if(CANx == LPC_CAN1) + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE); + } + else + { + /* Turn on power and clock for CAN1 */ + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE); + } +} + +/********************************************************************//** + * @brief Setup Acceptance Filter Look-Up Table + * @param[in] CANAFx pointer to LPC_CANAF_TypeDef + * Should be: LPC_CANAF + * @param[in] AFSection the pointer to AF_SectionDef structure + * It contain information about 5 sections will be install in AFLUT + * @return CAN Error could be: + * - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available + * - CAN_AF_ENTRY_ERROR: table error-violation of ascending numerical order + * - CAN_OK: ID is added into table successfully + *********************************************************************/ +CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection) +{ + uint8_t ctrl1,ctrl2; + uint8_t dis1, dis2; + uint16_t SID, SID_temp,i, count = 0; + uint32_t EID, EID_temp, entry, buf; + uint16_t lowerSID, upperSID; + uint32_t lowerEID, upperEID; + + CHECK_PARAM(PARAM_CANAFx(CANAFx)); + CANAFx->AFMR = 0x01; + +/***** setup FullCAN Table *****/ + if(AFSection->FullCAN_Sec == NULL) + { + FULLCAN_ENABLE = DISABLE; + } + else + { + FULLCAN_ENABLE = ENABLE; + for(i=0;i<(AFSection->FC_NumEntry);i++) + { + if(count + 1 > 64) + { + return CAN_OBJECTS_FULL_ERROR; + } + ctrl1 = AFSection->FullCAN_Sec->controller; + SID = AFSection->FullCAN_Sec->id_11; + dis1 = AFSection->FullCAN_Sec->disable; + + CHECK_PARAM(PARAM_CTRL(ctrl1)); + CHECK_PARAM(PARAM_ID_11(SID)); + CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); + entry = 0x00; //reset entry value + if((CANAF_FullCAN_cnt & 0x00000001)==0) + { + if(count!=0x00) + { + buf = LPC_CANAF_RAM->mask[count-1]; + SID_temp = (buf & 0x000003FF); + if(SID_temp > SID) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27); + LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; + LPC_CANAF_RAM->mask[count] |= entry; + CANAF_FullCAN_cnt++; + } + else + { + buf = LPC_CANAF_RAM->mask[count]; + SID_temp = (buf & 0x03FF0000)>>16; + if(SID_temp > SID) + { + return CAN_AF_ENTRY_ERROR; + } + entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11); + LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; + LPC_CANAF_RAM->mask[count]|= entry; + count++; + CANAF_FullCAN_cnt++; + } + AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry)); + } + } + +/***** Setup Explicit Standard Frame Format Section *****/ + if(AFSection->SFF_Sec != NULL) + { + for(i=0;i<(AFSection->SFF_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + ctrl1 = AFSection->SFF_Sec->controller; + SID = AFSection->SFF_Sec->id_11; + dis1 = AFSection->SFF_Sec->disable; + + //check parameter + CHECK_PARAM(PARAM_CTRL(ctrl1)); + CHECK_PARAM(PARAM_ID_11(SID)); + CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); + + entry = 0x00; //reset entry value + if((CANAF_std_cnt & 0x00000001)==0) + { + if(CANAF_std_cnt !=0 ) + { + buf = LPC_CANAF_RAM->mask[count-1]; + SID_temp = (buf & 0x00000FFF); + if(SID_temp > SID) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1<<29)|(dis1<<28)|(SID<<16); + LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; + LPC_CANAF_RAM->mask[count] |= entry; + CANAF_std_cnt++; + } + else + { + buf = LPC_CANAF_RAM->mask[count]; + SID_temp = (buf & 0x0FFF0000)>>16; + if(SID_temp > SID) + { + return CAN_AF_ENTRY_ERROR; + } + entry = (ctrl1<<13)|(dis1<<12)|(SID<<0); + LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; + LPC_CANAF_RAM->mask[count] |= entry; + count++; + CANAF_std_cnt++; + } + AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry)); + } + } + +/***** Setup Group of Standard Frame Format Identifier Section *****/ + if(AFSection->SFF_GPR_Sec != NULL) + { + for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + ctrl1 = AFSection->SFF_GPR_Sec->controller1; + ctrl2 = AFSection->SFF_GPR_Sec->controller2; + dis1 = AFSection->SFF_GPR_Sec->disable1; + dis2 = AFSection->SFF_GPR_Sec->disable2; + lowerSID = AFSection->SFF_GPR_Sec->lowerID; + upperSID = AFSection->SFF_GPR_Sec->upperID; + + /* check parameter */ + CHECK_PARAM(PARAM_CTRL(ctrl1)); + CHECK_PARAM(PARAM_CTRL(ctrl2)); + CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); + CHECK_PARAM(PARAM_MSG_DISABLE(dis2)); + CHECK_PARAM(PARAM_ID_11(lowerSID)); + CHECK_PARAM(PARAM_ID_11(upperSID)); + + entry = 0x00; + if(CANAF_gstd_cnt!=0) + { + buf = LPC_CANAF_RAM->mask[count-1]; + SID_temp = buf & 0x00000FFF; + if(SID_temp > lowerSID) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)| \ + (ctrl2 << 13)|(dis2 << 12)|(upperSID << 0); + LPC_CANAF_RAM->mask[count] = entry; + CANAF_gstd_cnt++; + count++; + AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry)); + } + } + +/***** Setup Explicit Extend Frame Format Identifier Section *****/ + if(AFSection->EFF_Sec != NULL) + { + for(i=0;i<(AFSection->EFF_NumEntry);i++) + { + if(count + 1 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + EID = AFSection->EFF_Sec->ID_29; + ctrl1 = AFSection->EFF_Sec->controller; + + // check parameter + CHECK_PARAM(PARAM_ID_29(EID)); + CHECK_PARAM(PARAM_CTRL(ctrl1)); + + entry = 0x00; //reset entry value + if(CANAF_ext_cnt != 0) + { + buf = LPC_CANAF_RAM->mask[count-1]; + EID_temp = buf & 0x0FFFFFFF; + if(EID_temp > EID) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1 << 29)|(EID << 0); + LPC_CANAF_RAM->mask[count] = entry; + CANAF_ext_cnt ++; + count++; + AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry)); + } + } + +/***** Setup Group of Extended Frame Format Identifier Section *****/ + if(AFSection->EFF_GPR_Sec != NULL) + { + for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++) + { + if(count + 2 > 512) + { + return CAN_OBJECTS_FULL_ERROR; + } + ctrl1 = AFSection->EFF_GPR_Sec->controller1; + ctrl2 = AFSection->EFF_GPR_Sec->controller2; + lowerEID = AFSection->EFF_GPR_Sec->lowerEID; + upperEID = AFSection->EFF_GPR_Sec->upperEID; + + //check parameter + CHECK_PARAM(PARAM_CTRL(ctrl1)); + CHECK_PARAM(PARAM_CTRL(ctrl2)); + CHECK_PARAM(PARAM_ID_29(lowerEID)); + CHECK_PARAM(PARAM_ID_29(upperEID)); + + entry = 0x00; + if(CANAF_gext_cnt != 0) + { + buf = LPC_CANAF_RAM->mask[count-1]; + EID_temp = buf & 0x0FFFFFFF; + if(EID_temp > lowerEID) + { + return CAN_AF_ENTRY_ERROR; + } + } + entry = (ctrl1 << 29)|(lowerEID << 0); + LPC_CANAF_RAM->mask[count++] = entry; + entry = (ctrl2 << 29)|(upperEID << 0); + LPC_CANAF_RAM->mask[count++] = entry; + CANAF_gext_cnt++; + AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry)); + } + } + //update address values + LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2; + LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2); + LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2); + LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2); + LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3); + + if(FULLCAN_ENABLE == DISABLE) + { + LPC_CANAF->AFMR = 0x00; // Normal mode + } + else + { + LPC_CANAF->AFMR = 0x04; + } + return CAN_OK; +} +/********************************************************************//** + * @brief Add Explicit ID into AF Look-Up Table dynamically. + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] id: The ID of entry will be added + * @param[in] format: is the type of ID Frame Format, should be: + * - STD_ID_FORMAT: 11-bit ID value + * - EXT_ID_FORMAT: 29-bit ID value + * @return CAN Error, could be: + * - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available + * - CAN_ID_EXIT_ERROR: ID exited in table + * - CAN_OK: ID is added into table successfully + *********************************************************************/ +CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t id, CAN_ID_FORMAT_Type format) +{ + uint32_t tmp0 = 0; + uint32_t buf0=0, buf1=0; + int16_t cnt1=0, cnt2=0, bound1=0, total=0; + + + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_ID_FORMAT(format)); + + if (CANx == LPC_CAN1) + { + tmp0 = 0; + } + else if (CANx == LPC_CAN2) + { + tmp0 = 1; + } + + /* Acceptance Filter Memory full - return */ + total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + if (total >= 512){ //don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + +/*********** Add Explicit Standard Identifier Frame Format entry *********/ + if(format == STD_ID_FORMAT) + { + id &= 0x07FF; + id |= (tmp0 << 13); /* Add controller number */ + /* Move all remaining sections one place up + if new entry will increase FullCAN list */ + if ((CANAF_std_cnt & 0x0001) == 0) + { + cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); + bound1 = total - cnt1; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + while(bound1--) + { + cnt1++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = buf0; + buf0 = buf1; + } + } + if (CANAF_std_cnt == 0) + { + cnt2 = (CANAF_FullCAN_cnt + 1)>>1; + /* For entering first ID */ + LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16); + } + else if (CANAF_std_cnt == 1) + { + cnt2 = (CANAF_FullCAN_cnt + 1)>>1; + /* For entering second ID */ + if ((LPC_CANAF_RAM->mask[cnt2] >> 16) > id) + { + LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16); + } + else + { + LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id; + } + } + else + { + /* Find where to insert new ID */ + cnt1 = (CANAF_FullCAN_cnt+1)>>1; + cnt2 = CANAF_std_cnt; + bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); + while (cnt1 < bound1) + { + /* Loop through standard existing IDs */ + if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) + { + cnt2 = cnt1 * 2; + break; + } + + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) + { + cnt2 = cnt1 * 2 + 1; + break; + } + + cnt1++; + } + /* cnt1 = U32 where to insert new ID */ + /* cnt2 = U16 where to insert new ID */ + + if (cnt1 == bound1) + { + /* Adding ID as last entry */ + /* Even number of IDs exists */ + if ((CANAF_std_cnt & 0x0001) == 0) + { + LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); + } + /* Odd number of IDs exists */ + else + { + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; + } + } + else + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + if ((cnt2 & 0x0001) == 0) + { + /* Insert new mask to even address*/ + buf1 = (id << 16) | (buf0 >> 16); + } + else + { + /* Insert new mask to odd address */ + buf1 = (buf0 & 0xFFFF0000) | id; + } + LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ + bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1; + /* Move all remaining standard mask entries one place up */ + while (cnt1 < bound1) + { + cnt1++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); + buf0 = buf1; + } + + if ((CANAF_std_cnt & 0x0001) == 0) + { + /* Even number of IDs exists */ + LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF); + } + } + } + CANAF_std_cnt++; + //update address values + LPC_CANAF->SFF_GRP_sa +=0x04 ; + LPC_CANAF->EFF_sa +=0x04 ; + LPC_CANAF->EFF_GRP_sa +=0x04; + LPC_CANAF->ENDofTable +=0x04; + } + +/*********** Add Explicit Extended Identifier Frame Format entry *********/ + else + { + /* Add controller number */ + id |= (tmp0) << 29; + + cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt); + cnt2 = 0; + while (cnt2 < CANAF_ext_cnt) + { + /* Loop through extended existing masks*/ + if (LPC_CANAF_RAM->mask[cnt1] > id) + { + break; + } + cnt1++;/* cnt1 = U32 where to insert new mask */ + cnt2++; + } + + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + LPC_CANAF_RAM->mask[cnt1] = id; /* Insert mask */ + + CANAF_ext_cnt++; + + bound1 = total; + /* Move all remaining extended mask entries one place up*/ + while (cnt2 < bound1) + { + cnt1++; + cnt2++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = buf0; + buf0 = buf1; + } + /* update address values */ + LPC_CANAF->EFF_GRP_sa += 4; + LPC_CANAF->ENDofTable += 4; + } + if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode + { + LPC_CANAF->AFMR = 0x00;//not use FullCAN mode + } + else + { + LPC_CANAF->AFMR = 0x04; + } + + return CAN_OK; +} + +/********************************************************************//** + * @brief Load FullCAN entry into AFLUT + * @param[in] CANx: CAN peripheral selected, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] id: identifier of entry that will be added + * @return CAN_ERROR, could be: + * - CAN_OK: loading is successful + * - CAN_ID_EXIT_ERROR: ID exited in FullCAN Section + * - CAN_OBJECTS_FULL_ERROR: no more space available + *********************************************************************/ +CAN_ERROR CAN_LoadFullCANEntry (LPC_CAN_TypeDef* CANx, uint16_t id) +{ + uint32_t ctrl0 = 0; + uint32_t buf0=0, buf1=0, buf2=0; + uint32_t tmp0=0, tmp1=0, tmp2=0; + int16_t cnt1=0, cnt2=0, bound1=0, total=0; + + CHECK_PARAM(PARAM_CANx(CANx)); + + if (CANx == LPC_CAN1) + { + ctrl0 = 0; + } + else if (CANx == LPC_CAN2) + { + ctrl0 = 1; + } + + /* Acceptance Filter Memory full - return */ + total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + //don't have enough space for this fullCAN Entry and its Object(3*32 bytes) + if ((total >=508)||(CANAF_FullCAN_cnt>=64)){ + return CAN_OBJECTS_FULL_ERROR; + } + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + + /* Add mask for standard identifiers */ + id &= 0x07FF; + id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */ +// total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + /* Move all remaining sections one place up + if new entry will increase FullCAN list */ + if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0)) + { + //then remove remaining section + cnt1 = (CANAF_FullCAN_cnt >> 1); + bound1 = total; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + + while (bound1--) + { + cnt1++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = buf0; + buf0 = buf1; + } + } + if (CANAF_FullCAN_cnt == 0) + { + /* For entering first ID */ + LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16); + } + else if (CANAF_FullCAN_cnt == 1) + { + /* For entering second ID */ + if ((LPC_CANAF_RAM->mask[0] >> 16) > id) + { + LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16); + } + else + { + LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id; + } + } + else + { + /* Find where to insert new ID */ + cnt1 = 0; + cnt2 = CANAF_FullCAN_cnt; + bound1 = (CANAF_FullCAN_cnt - 1) >> 1; + while (cnt1 <= bound1) + { + /* Loop through standard existing IDs */ + if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) + { + cnt2 = cnt1 * 2; + break; + } + + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) + { + cnt2 = cnt1 * 2 + 1; + break; + } + + cnt1++; + } + /* cnt1 = U32 where to insert new ID */ + /* cnt2 = U16 where to insert new ID */ + + if (cnt1 > bound1) + { + /* Adding ID as last entry */ + /* Even number of IDs exists */ + if ((CANAF_FullCAN_cnt & 0x0001) == 0) + { + LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); + } + /* Odd number of IDs exists */ + else + { + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; + } + } + else + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ + if ((cnt2 & 0x0001) == 0) + { + /* Insert new mask to even address*/ + buf1 = (id << 16) | (buf0 >> 16); + } + else + { + /* Insert new mask to odd address */ + buf1 = (buf0 & 0xFFFF0000) | id; + } + LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ + bound1 = CANAF_FullCAN_cnt >> 1; + /* Move all remaining standard mask entries one place up */ + while (cnt1 < bound1) + { + cnt1++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); + buf0 = buf1; + } + + if ((CANAF_FullCAN_cnt & 0x0001) == 0) + { + /* Even number of IDs exists */ + LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) + | (0x0000FFFF); + } + } + } + //restruct FulCAN Object Section + bound1 = CANAF_FullCAN_cnt - cnt2; + cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + buf2 = LPC_CANAF_RAM->mask[cnt1+2]; + LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00; + cnt1+=3; + while(bound1--) + { + tmp0 = LPC_CANAF_RAM->mask[cnt1]; + tmp1 = LPC_CANAF_RAM->mask[cnt1+1]; + tmp2 = LPC_CANAF_RAM->mask[cnt1+2]; + LPC_CANAF_RAM->mask[cnt1]= buf0; + LPC_CANAF_RAM->mask[cnt1+1]= buf1; + LPC_CANAF_RAM->mask[cnt1+2]= buf2; + buf0 = tmp0; + buf1 = tmp1; + buf2 = tmp2; + cnt1+=3; + } + CANAF_FullCAN_cnt++; + //update address values + LPC_CANAF->SFF_sa +=0x04; + LPC_CANAF->SFF_GRP_sa +=0x04 ; + LPC_CANAF->EFF_sa +=0x04 ; + LPC_CANAF->EFF_GRP_sa +=0x04; + LPC_CANAF->ENDofTable +=0x04; + + LPC_CANAF->AFMR = 0x04; + return CAN_OK; +} + +/********************************************************************//** + * @brief Load Group entry into AFLUT + * @param[in] CANx: CAN peripheral selected, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] lowerID, upperID: lower and upper identifier of entry + * @param[in] format: type of ID format, should be: + * - STD_ID_FORMAT: Standard ID format (11-bit value) + * - EXT_ID_FORMAT: Extended ID format (29-bit value) + * @return CAN_ERROR, could be: + * - CAN_OK: loading is successful + * - CAN_CONFLICT_ID_ERROR: Conflict ID occurs + * - CAN_OBJECTS_FULL_ERROR: no more space available + *********************************************************************/ +CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \ + uint32_t upperID, CAN_ID_FORMAT_Type format) +{ + uint16_t tmp = 0; + uint32_t buf0 = 0, buf1 = 0, entry1, entry2, LID,UID; + int16_t cnt1, bound1, total; + + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_ID_FORMAT(format)); + + if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR; + if(CANx == LPC_CAN1) + { + tmp = 0; + } + else + { + tmp = 1; + } + + total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + +/*********Add Group of Standard Identifier Frame Format************/ + if(format == STD_ID_FORMAT) + { + if ((total >= 512)){//don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + lowerID &=0x7FF; //mask ID + upperID &=0x7FF; + entry1 = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0); + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1); + + //if this is the first Group standard ID entry + if(CANAF_gstd_cnt == 0) + { + LPC_CANAF_RAM->mask[cnt1] = entry1; + } + else + { + //find the position to add new Group entry + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt; + while(cnt1 < bound1) + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; + LID = (buf0 >> 16)&0x7FF; + UID = buf0 & 0x7FF; + if (upperID <= LID) + { + //add new entry before this entry + LPC_CANAF_RAM->mask[cnt1] = entry1; + break; + } + else if (lowerID >= UID) + { + //load next entry to compare + cnt1 ++; + } + else + return CAN_CONFLICT_ID_ERROR; + } + if(cnt1 >= bound1) + { + //add new entry at the last position in this list + buf0 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = entry1; + } + + //remove all remaining entry of this section one place up + bound1 = total - cnt1; + while(bound1--) + { + cnt1++; + buf1 = LPC_CANAF_RAM->mask[cnt1]; + LPC_CANAF_RAM->mask[cnt1] = buf0; + buf0 = buf1; + } + } + CANAF_gstd_cnt++; + //update address values + LPC_CANAF->EFF_sa +=0x04 ; + LPC_CANAF->EFF_GRP_sa +=0x04; + LPC_CANAF->ENDofTable +=0x04; + } + + +/*********Add Group of Extended Identifier Frame Format************/ + else + { + if ((total >= 511)){//don't have enough space + return CAN_OBJECTS_FULL_ERROR; + } + lowerID &= 0x1FFFFFFF; //mask ID + upperID &= 0x1FFFFFFF; + entry1 = (tmp << 29)|(lowerID << 0); + entry2 = (tmp << 29)|(upperID << 0); + + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt; + //if this is the first Group standard ID entry + if(CANAF_gext_cnt == 0) + { + LPC_CANAF_RAM->mask[cnt1] = entry1; + LPC_CANAF_RAM->mask[cnt1+1] = entry2; + } + else + { + //find the position to add new Group entry + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \ + + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + while(cnt1 < bound1) + { + buf0 = LPC_CANAF_RAM->mask[cnt1]; + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + LID = buf0 & 0x1FFFFFFF; //mask ID + UID = buf1 & 0x1FFFFFFF; + if (upperID <= LID) + { + //add new entry before this entry + LPC_CANAF_RAM->mask[cnt1] = entry1; + LPC_CANAF_RAM->mask[++cnt1] = entry2; + break; + } + else if (lowerID >= UID) + { + //load next entry to compare + cnt1 +=2; + } + else + return CAN_CONFLICT_ID_ERROR; + } + if(cnt1 >= bound1) + { + //add new entry at the last position in this list + buf0 = LPC_CANAF_RAM->mask[cnt1]; + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + LPC_CANAF_RAM->mask[cnt1] = entry1; + LPC_CANAF_RAM->mask[++cnt1] = entry2; + } + //remove all remaining entry of this section two place up + bound1 = total - cnt1 + 1; + cnt1++; + while(bound1>0) + { + entry1 = LPC_CANAF_RAM->mask[cnt1]; + entry2 = LPC_CANAF_RAM->mask[cnt1+1]; + LPC_CANAF_RAM->mask[cnt1] = buf0; + LPC_CANAF_RAM->mask[cnt1+1] = buf1; + buf0 = entry1; + buf1 = entry2; + cnt1 +=2; + bound1 -=2; + } + } + CANAF_gext_cnt++; + //update address values + LPC_CANAF->ENDofTable +=0x08; + } + LPC_CANAF->AFMR = 0x04; + return CAN_OK; +} + +/********************************************************************//** + * @brief Remove AFLUT entry (FullCAN entry and Explicit Standard entry) + * @param[in] EntryType: the type of entry that want to remove, should be: + * - FULLCAN_ENTRY + * - EXPLICIT_STANDARD_ENTRY + * - GROUP_STANDARD_ENTRY + * - EXPLICIT_EXTEND_ENTRY + * - GROUP_EXTEND_ENTRY + * @param[in] position: the position of this entry in its section + * Note: the first position is 0 + * @return CAN_ERROR, could be: + * - CAN_OK: removing is successful + * - CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit + *********************************************************************/ +CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position) +{ + uint16_t cnt, bound, total; + uint32_t buf0, buf1; + CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType)); + CHECK_PARAM(PARAM_POSITION(position)); + + /* Setup Acceptance Filter Configuration + Acceptance Filter Mode Register = Off */ + LPC_CANAF->AFMR = 0x00000001; + total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \ + CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + + +/************** Remove FullCAN Entry *************/ + if(EntryType == FULLCAN_ENTRY) + { + if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = position >> 1; + buf0 = LPC_CANAF_RAM->mask[cnt]; + bound = (CANAF_FullCAN_cnt - position -1)>>1; + if((position & 0x0001) == 0) //event position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); + buf0 = buf1; + cnt++; + } + } + else //odd position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16); + LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16; + buf0 = buf1<<16; + cnt++; + } + } + if((CANAF_FullCAN_cnt & 0x0001) == 0) + { + if((position & 0x0001)==0) + LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); + else + LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; + } + else + { + //remove all remaining section one place down + cnt = (CANAF_FullCAN_cnt + 1)>>1; + bound = total + CANAF_FullCAN_cnt * 3; + while(bound>cnt) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt-1]=0x00; + //update address values + LPC_CANAF->SFF_sa -=0x04; + LPC_CANAF->SFF_GRP_sa -=0x04 ; + LPC_CANAF->EFF_sa -=0x04 ; + LPC_CANAF->EFF_GRP_sa -=0x04; + LPC_CANAF->ENDofTable -=0x04; + } + CANAF_FullCAN_cnt--; + + //delete its FullCAN Object in the FullCAN Object section + //remove all remaining FullCAN Object three place down + cnt = total + position * 3; + bound = (CANAF_FullCAN_cnt - position + 1) * 3; + + while(bound) + { + LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];; + LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4]; + LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5]; + bound -=3; + cnt +=3; + } + } + } + +/************** Remove Explicit Standard ID Entry *************/ + else if(EntryType == EXPLICIT_STANDARD_ENTRY) + { + if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1); + buf0 = LPC_CANAF_RAM->mask[cnt]; + bound = (CANAF_std_cnt - position - 1)>>1; + if((position & 0x0001) == 0) //event position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); + buf0 = buf1; + cnt++; + } + } + else //odd position + { + while(bound--) + { + //remove all remaining FullCAN entry one place down + buf1 = LPC_CANAF_RAM->mask[cnt+1]; + LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16); + LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16; + buf0 = buf1<<16; + cnt++; + } + } + if((CANAF_std_cnt & 0x0001) == 0) + { + if((position & 0x0001)==0) + LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); + else + LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; + } + else + { + //remove all remaining section one place down + cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1); + bound = total + CANAF_FullCAN_cnt * 3; + while(bound>cnt) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt-1]=0x00; + //update address value + LPC_CANAF->SFF_GRP_sa -=0x04 ; + LPC_CANAF->EFF_sa -=0x04 ; + LPC_CANAF->EFF_GRP_sa -=0x04; + LPC_CANAF->ENDofTable -=0x04; + } + CANAF_std_cnt--; + } + } + +/************** Remove Group of Standard ID Entry *************/ + else if(EntryType == GROUP_STANDARD_ENTRY) + { + if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1; + bound = total + CANAF_FullCAN_cnt * 3; + while (cnt<bound) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt-1]=0x00; + } + CANAF_gstd_cnt--; + //update address value + LPC_CANAF->EFF_sa -=0x04; + LPC_CANAF->EFF_GRP_sa -=0x04; + LPC_CANAF->ENDofTable -=0x04; + } + +/************** Remove Explicit Extended ID Entry *************/ + else if(EntryType == EXPLICIT_EXTEND_ENTRY) + { + if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1; + bound = total + CANAF_FullCAN_cnt * 3; + while (cnt<bound) + { + LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; + cnt++; + } + LPC_CANAF_RAM->mask[cnt-1]=0x00; + } + CANAF_ext_cnt--; + LPC_CANAF->EFF_GRP_sa -=0x04; + LPC_CANAF->ENDofTable -=0x04; + } + +/************** Remove Group of Extended ID Entry *************/ + else + { + if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt)) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + cnt = total - (CANAF_gext_cnt<<1) + (position<<1); + bound = total + CANAF_FullCAN_cnt * 3; + while (cnt<bound) + { + //remove all remaining entry two place up + LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2]; + LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3]; + cnt+=2; + } + } + CANAF_gext_cnt--; + LPC_CANAF->ENDofTable -=0x08; + } + LPC_CANAF->AFMR = 0x04; + return CAN_OK; +} + +/********************************************************************//** + * @brief Send message data + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] CAN_Msg point to the CAN_MSG_Type Structure, it contains message + * information such as: ID, DLC, RTR, ID Format + * @return Status: + * - SUCCESS: send message successfully + * - ERROR: send message unsuccessfully + *********************************************************************/ +Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) +{ + uint32_t data; + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format)); + if(CAN_Msg->format==STD_ID_FORMAT) + { + CHECK_PARAM(PARAM_ID_11(CAN_Msg->id)); + } + else + { + CHECK_PARAM(PARAM_ID_29(CAN_Msg->id)); + } + CHECK_PARAM(PARAM_DLC(CAN_Msg->len)); + CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type)); + + //Check status of Transmit Buffer 1 + if (CANx->SR & (1<<2)) + { + /* Transmit Channel 1 is available */ + /* Write frame informations and frame data into its CANxTFI1, + * CANxTID1, CANxTDA1, CANxTDB1 register */ + CANx->TFI1 &= ~0x000F0000; + CANx->TFI1 |= (CAN_Msg->len)<<16; + if(CAN_Msg->type == REMOTE_FRAME) + { + CANx->TFI1 |= (1<<30); //set bit RTR + } + else + { + CANx->TFI1 &= ~(1<<30); + } + if(CAN_Msg->format == EXT_ID_FORMAT) + { + CANx->TFI1 |= (1UL<<31); //set bit FF + } + else + { + CANx->TFI1 &= ~(1UL<<31); + } + + /* Write CAN ID*/ + CANx->TID1 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); + CANx->TDA1 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); + CANx->TDB1 = data; + + /*Write transmission request*/ + CANx->CMR = 0x21; + return SUCCESS; + } + //check status of Transmit Buffer 2 + else if(CANx->SR & (1<<10)) + { + /* Transmit Channel 2 is available */ + /* Write frame informations and frame data into its CANxTFI2, + * CANxTID2, CANxTDA2, CANxTDB2 register */ + CANx->TFI2 &= ~0x000F0000; + CANx->TFI2 |= (CAN_Msg->len)<<16; + if(CAN_Msg->type == REMOTE_FRAME) + { + CANx->TFI2 |= (1<<30); //set bit RTR + } + else + { + CANx->TFI2 &= ~(1<<30); + } + if(CAN_Msg->format == EXT_ID_FORMAT) + { + CANx->TFI2 |= (1UL<<31); //set bit FF + } + else + { + CANx->TFI2 &= ~(1UL<<31); + } + + /* Write CAN ID*/ + CANx->TID2 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); + CANx->TDA2 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); + CANx->TDB2 = data; + + /*Write transmission request*/ + CANx->CMR = 0x41; + return SUCCESS; + } + //check status of Transmit Buffer 3 + else if (CANx->SR & (1<<18)) + { + /* Transmit Channel 3 is available */ + /* Write frame informations and frame data into its CANxTFI3, + * CANxTID3, CANxTDA3, CANxTDB3 register */ + CANx->TFI3 &= ~0x000F0000; + CANx->TFI3 |= (CAN_Msg->len)<<16; + if(CAN_Msg->type == REMOTE_FRAME) + { + CANx->TFI3 |= (1<<30); //set bit RTR + } + else + { + CANx->TFI3 &= ~(1<<30); + } + if(CAN_Msg->format == EXT_ID_FORMAT) + { + CANx->TFI3 |= (1UL<<31); //set bit FF + } + else + { + CANx->TFI3 &= ~(1UL<<31); + } + + /* Write CAN ID*/ + CANx->TID3 = CAN_Msg->id; + + /*Write first 4 data bytes*/ + data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); + CANx->TDA3 = data; + + /*Write second 4 data bytes*/ + data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); + CANx->TDB3 = data; + + /*Write transmission request*/ + CANx->CMR = 0x81; + return SUCCESS; + } + else + { + return ERROR; + } +} + +/********************************************************************//** + * @brief Receive message data + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received + * message information such as: ID, DLC, RTR, ID Format + * @return Status: + * - SUCCESS: receive message successfully + * - ERROR: receive message unsuccessfully + *********************************************************************/ +Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) +{ + uint32_t data; + + CHECK_PARAM(PARAM_CANx(CANx)); + + //check status of Receive Buffer + if((CANx->SR &0x00000001)) + { + /* Receive message is available */ + /* Read frame informations */ + CAN_Msg->format = (uint8_t)(((CANx->RFS) & 0x80000000)>>31); + CAN_Msg->type = (uint8_t)(((CANx->RFS) & 0x40000000)>>30); + CAN_Msg->len = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16); + + + /* Read CAN message identifier */ + CAN_Msg->id = CANx->RID; + + /* Read the data if received message was DATA FRAME */ + if (CAN_Msg->type == DATA_FRAME) + { + /* Read first 4 data bytes */ + data = CANx->RDA; + *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; + *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;; + *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16; + *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24; + + /* Read second 4 data bytes */ + data = CANx->RDB; + *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; + *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8; + *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16; + *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24; + + /*release receive buffer*/ + CANx->CMR = 0x04; + } + else + { + /* Received Frame is a Remote Frame, not have data, we just receive + * message information only */ + CANx->CMR = 0x04; /*release receive buffer*/ + return SUCCESS; + } + } + else + { + // no receive message available + return ERROR; + } + return SUCCESS; +} + +/********************************************************************//** + * @brief Receive FullCAN Object + * @param[in] CANAFx: CAN Acceptance Filter register, should be: LPC_CANAF + * @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received + * message information such as: ID, DLC, RTR, ID Format + * @return CAN_ERROR, could be: + * - CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received + * - CAN_OK: Received FullCAN Object successful + * + *********************************************************************/ +CAN_ERROR FCAN_ReadObj (LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg) +{ + uint32_t *pSrc, data; + uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx; + + CHECK_PARAM(PARAM_CANAFx(CANAFx)); + + interrut_word = 0; + + if (LPC_CANAF->FCANIC0 != 0) + { + interrut_word = LPC_CANAF->FCANIC0; + head_idx = 0; + tail_idx = 31; + } + else if (LPC_CANAF->FCANIC1 != 0) + { + interrut_word = LPC_CANAF->FCANIC1; + head_idx = 32; + tail_idx = 63; + } + + if (interrut_word != 0) + { + /* Detect for interrupt pending */ + msg_idx = 0; + for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++) + { + test_bit = interrut_word & 0x1; + interrut_word = interrut_word >> 1; + + if (test_bit) + { + pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12); + + /* Has been finished updating the content */ + if ((*pSrc & 0x03000000L) == 0x03000000L) + { + /*clear semaphore*/ + *pSrc &= 0xFCFFFFFF; + + /*Set to DatA*/ + pSrc++; + /* Copy to dest buf */ + data = *pSrc; + *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; + *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8; + *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16; + *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24; + + /*Set to DatB*/ + pSrc++; + /* Copy to dest buf */ + data = *pSrc; + *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; + *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8; + *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16; + *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24; + /*Back to Dat1*/ + pSrc -= 2; + + CAN_Msg->id = *pSrc & 0x7FF; + CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F; + CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value + CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01; + /*Re-read semaphore*/ + if ((*pSrc & 0x03000000L) == 0) + { + return CAN_OK; + } + } + } + } + } + return CAN_FULL_OBJ_NOT_RCV; +} +/********************************************************************//** + * @brief Get CAN Control Status + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] arg: type of CAN status to get from CAN status register + * Should be: + * - CANCTRL_GLOBAL_STS: CAN Global Status + * - CANCTRL_INT_CAP: CAN Interrupt and Capture + * - CANCTRL_ERR_WRN: CAN Error Warning Limit + * - CANCTRL_STS: CAN Control Status + * @return Current Control Status that you want to get value + *********************************************************************/ +uint32_t CAN_GetCTRLStatus (LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_CTRL_STS_TYPE(arg)); + + switch (arg) + { + case CANCTRL_GLOBAL_STS: + return CANx->GSR; + + case CANCTRL_INT_CAP: + return CANx->ICR; + + case CANCTRL_ERR_WRN: + return CANx->EWL; + + default: // CANCTRL_STS + return CANx->SR; + } +} +/********************************************************************//** + * @brief Get CAN Central Status + * @param[in] CANCRx point to LPC_CANCR_TypeDef, should be: LPC_CANCR + * @param[in] arg: type of CAN status to get from CAN Central status register + * Should be: + * - CANCR_TX_STS: Central CAN Tx Status + * - CANCR_RX_STS: Central CAN Rx Status + * - CANCR_MS: Central CAN Miscellaneous Status + * @return Current Central Status that you want to get value + *********************************************************************/ +uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg) +{ + CHECK_PARAM(PARAM_CANCRx(CANCRx)); + CHECK_PARAM(PARAM_CR_STS_TYPE(arg)); + + switch (arg) + { + case CANCR_TX_STS: + return CANCRx->CANTxSR; + + case CANCR_RX_STS: + return CANCRx->CANRxSR; + + default: // CANCR_MS + return CANCRx->CANMSR; + } +} +/********************************************************************//** + * @brief Enable/Disable CAN Interrupt + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] arg: type of CAN interrupt that you want to enable/disable + * Should be: + * - CANINT_RIE: CAN Receiver Interrupt Enable + * - CANINT_TIE1: CAN Transmit Interrupt Enable + * - CANINT_EIE: CAN Error Warning Interrupt Enable + * - CANINT_DOIE: CAN Data Overrun Interrupt Enable + * - CANINT_WUIE: CAN Wake-Up Interrupt Enable + * - CANINT_EPIE: CAN Error Passive Interrupt Enable + * - CANINT_ALIE: CAN Arbitration Lost Interrupt Enable + * - CANINT_BEIE: CAN Bus Error Interrupt Enable + * - CANINT_IDIE: CAN ID Ready Interrupt Enable + * - CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2 + * - CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3 + * - CANINT_FCE: FullCAN Interrupt Enable + * @param[in] NewState: New state of this function, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_INT_EN_TYPE(arg)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if(NewState == ENABLE) + { + if(arg==CANINT_FCE) + { + LPC_CANAF->AFMR = 0x01; + LPC_CANAF->FCANIE = 0x01; + LPC_CANAF->AFMR = 0x04; + } + else + CANx->IER |= (1 << arg); + } + else + { + if(arg==CANINT_FCE){ + LPC_CANAF->AFMR = 0x01; + LPC_CANAF->FCANIE = 0x01; + LPC_CANAF->AFMR = 0x00; + } + else + CANx->IER &= ~(1 << arg); + } +} + +/********************************************************************//** + * @brief Setting Acceptance Filter mode + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @param[in] AFMode: type of AF mode that you want to set, should be: + * - CAN_Normal: Normal mode + * - CAN_AccOff: Acceptance Filter Off Mode + * - CAN_AccBP: Acceptance Fileter Bypass Mode + * - CAN_eFCAN: FullCAN Mode Enhancement + * @return none + *********************************************************************/ +void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode) +{ + CHECK_PARAM(PARAM_CANAFx(CANAFx)); + CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode)); + + switch(AFMode) + { + case CAN_Normal: + CANAFx->AFMR = 0x00; + break; + case CAN_AccOff: + CANAFx->AFMR = 0x01; + break; + case CAN_AccBP: + CANAFx->AFMR = 0x02; + break; + case CAN_eFCAN: + CANAFx->AFMR = 0x04; + break; + } +} + +/********************************************************************//** + * @brief Enable/Disable CAN Mode + * @param[in] CANx pointer to LPC_CAN_TypeDef, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] mode: type of CAN mode that you want to enable/disable, should be: + * - CAN_OPERATING_MODE: Normal Operating Mode + * - CAN_RESET_MODE: Reset Mode + * - CAN_LISTENONLY_MODE: Listen Only Mode + * - CAN_SELFTEST_MODE: Self Test Mode + * - CAN_TXPRIORITY_MODE: Transmit Priority Mode + * - CAN_SLEEP_MODE: Sleep Mode + * - CAN_RXPOLARITY_MODE: Receive Polarity Mode + * - CAN_TEST_MODE: Test Mode + * @param[in] NewState: New State of this function, should be: + * - ENABLE + * - DISABLE + * @return none + *********************************************************************/ +void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + CHECK_PARAM(PARAM_MODE_TYPE(mode)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + switch(mode) + { + case CAN_OPERATING_MODE: + CANx->MOD = 0x00; + break; + case CAN_RESET_MODE: + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_RM; + else + CANx->MOD &= ~CAN_MOD_RM; + break; + case CAN_LISTENONLY_MODE: + CANx->MOD |=CAN_MOD_RM;//Enter Reset mode + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_LOM; + else + CANx->MOD &=~CAN_MOD_LOM; + CANx->MOD &=~CAN_MOD_RM;//Release Reset mode + break; + case CAN_SELFTEST_MODE: + CANx->MOD |=CAN_MOD_RM;//Enter Reset mode + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_STM; + else + CANx->MOD &=~CAN_MOD_STM; + CANx->MOD &=~CAN_MOD_RM;//Release Reset mode + break; + case CAN_TXPRIORITY_MODE: + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_TPM; + else + CANx->MOD &=~CAN_MOD_TPM; + break; + case CAN_SLEEP_MODE: + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_SM; + else + CANx->MOD &=~CAN_MOD_SM; + break; + case CAN_RXPOLARITY_MODE: + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_RPM; + else + CANx->MOD &=~CAN_MOD_RPM; + break; + case CAN_TEST_MODE: + if(NewState == ENABLE) + CANx->MOD |=CAN_MOD_TM; + else + CANx->MOD &=~CAN_MOD_TM; + break; + } +} +/*********************************************************************//** + * @brief Set CAN command request + * @param[in] CANx point to CAN peripheral selected, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @param[in] CMRType command request type, should be: + * - CAN_CMR_TR: Transmission request + * - CAN_CMR_AT: Abort Transmission request + * - CAN_CMR_RRB: Release Receive Buffer request + * - CAN_CMR_CDO: Clear Data Overrun request + * - CAN_CMR_SRR: Self Reception request + * - CAN_CMR_STB1: Select Tx Buffer 1 request + * - CAN_CMR_STB2: Select Tx Buffer 2 request + * - CAN_CMR_STB3: Select Tx Buffer 3 request + * @return CANICR (CAN interrupt and Capture register) value + **********************************************************************/ +void CAN_SetCommand(LPC_CAN_TypeDef* CANx, uint32_t CMRType) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + CANx->CMR |= CMRType; +} + +/*********************************************************************//** + * @brief Get CAN interrupt status + * @param[in] CANx point to CAN peripheral selected, should be: + * - LPC_CAN1: CAN1 peripheral + * - LPC_CAN2: CAN2 peripheral + * @return CANICR (CAN interrupt and Capture register) value + **********************************************************************/ +uint32_t CAN_IntGetStatus(LPC_CAN_TypeDef* CANx) +{ + CHECK_PARAM(PARAM_CANx(CANx)); + return CANx->ICR; +} + +/*********************************************************************//** + * @brief Check if FullCAN interrupt enable or not + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @return IntStatus, could be: + * - SET: if FullCAN interrupt is enable + * - RESET: if FullCAN interrupt is disable + **********************************************************************/ +IntStatus CAN_FullCANIntGetStatus (LPC_CANAF_TypeDef* CANAFx) +{ + CHECK_PARAM( PARAM_CANAFx(CANAFx)); + if (CANAFx->FCANIE) + return SET; + return RESET; +} + +/*********************************************************************//** + * @brief Get value of FullCAN interrupt and capture register + * @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF + * @param[in] type: FullCAN IC type, should be: + * - FULLCAN_IC0: FullCAN Interrupt Capture 0 + * - FULLCAN_IC1: FullCAN Interrupt Capture 1 + * @return FCANIC0 or FCANIC1 (FullCAN interrupt and Capture register) value + **********************************************************************/ +uint32_t CAN_FullCANPendGetStatus(LPC_CANAF_TypeDef* CANAFx, FullCAN_IC_Type type) +{ + CHECK_PARAM(PARAM_CANAFx(CANAFx)); + CHECK_PARAM( PARAM_FULLCAN_IC(type)); + if (type == FULLCAN_IC0) + return CANAFx->FCANIC0; + return CANAFx->FCANIC1; +} +/* End of Public Variables ---------------------------------------------------------- */ +/** + * @} + */ + +#endif /* _CAN */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_can.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_can.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,860 @@ +/***********************************************************************//** + * @file lpc17xx_can.h + * @brief Contains all macro definitions and function prototypes + * support for CAN firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup CAN CAN + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_CAN_H_ +#define LPC17XX_CAN_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup CAN_Public_Macros CAN Public Macros + * @{ + */ +#define MSG_ENABLE ((uint8_t)(0)) +#define MSG_DISABLE ((uint8_t)(1)) +#define CAN1_CTRL ((uint8_t)(0)) +#define CAN2_CTRL ((uint8_t)(1)) +#define PARAM_FULLCAN_IC(n) ((n==FULLCAN_IC0)||(n==FULLCAN_IC1)) +#define ID_11 1 +#define MAX_HW_FULLCAN_OBJ 64 +#define MAX_SW_FULLCAN_OBJ 32 + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup CAN_Private_Macros CAN Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for CAN Mode Register + **********************************************************************/ +/** CAN Reset mode */ +#define CAN_MOD_RM ((uint32_t)(1)) +/** CAN Listen Only Mode */ +#define CAN_MOD_LOM ((uint32_t)(1<<1)) +/** CAN Self Test mode */ +#define CAN_MOD_STM ((uint32_t)(1<<2)) +/** CAN Transmit Priority mode */ +#define CAN_MOD_TPM ((uint32_t)(1<<3)) +/** CAN Sleep mode */ +#define CAN_MOD_SM ((uint32_t)(1<<4)) +/** CAN Receive Polarity mode */ +#define CAN_MOD_RPM ((uint32_t)(1<<5)) +/** CAN Test mode */ +#define CAN_MOD_TM ((uint32_t)(1<<7)) + +/*********************************************************************//** + * Macro defines for CAN Command Register + **********************************************************************/ +/** CAN Transmission Request */ +#define CAN_CMR_TR ((uint32_t)(1)) +/** CAN Abort Transmission */ +#define CAN_CMR_AT ((uint32_t)(1<<1)) +/** CAN Release Receive Buffer */ +#define CAN_CMR_RRB ((uint32_t)(1<<2)) +/** CAN Clear Data Overrun */ +#define CAN_CMR_CDO ((uint32_t)(1<<3)) +/** CAN Self Reception Request */ +#define CAN_CMR_SRR ((uint32_t)(1<<4)) +/** CAN Select Tx Buffer 1 */ +#define CAN_CMR_STB1 ((uint32_t)(1<<5)) +/** CAN Select Tx Buffer 2 */ +#define CAN_CMR_STB2 ((uint32_t)(1<<6)) +/** CAN Select Tx Buffer 3 */ +#define CAN_CMR_STB3 ((uint32_t)(1<<7)) + +/*********************************************************************//** + * Macro defines for CAN Global Status Register + **********************************************************************/ +/** CAN Receive Buffer Status */ +#define CAN_GSR_RBS ((uint32_t)(1)) +/** CAN Data Overrun Status */ +#define CAN_GSR_DOS ((uint32_t)(1<<1)) +/** CAN Transmit Buffer Status */ +#define CAN_GSR_TBS ((uint32_t)(1<<2)) +/** CAN Transmit Complete Status */ +#define CAN_GSR_TCS ((uint32_t)(1<<3)) +/** CAN Receive Status */ +#define CAN_GSR_RS ((uint32_t)(1<<4)) +/** CAN Transmit Status */ +#define CAN_GSR_TS ((uint32_t)(1<<5)) +/** CAN Error Status */ +#define CAN_GSR_ES ((uint32_t)(1<<6)) +/** CAN Bus Status */ +#define CAN_GSR_BS ((uint32_t)(1<<7)) +/** CAN Current value of the Rx Error Counter */ +#define CAN_GSR_RXERR(n) ((uint32_t)((n&0xFF)<<16)) +/** CAN Current value of the Tx Error Counter */ +#define CAN_GSR_TXERR(n) ((uint32_t)(n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Interrupt and Capture Register + **********************************************************************/ +/** CAN Receive Interrupt */ +#define CAN_ICR_RI ((uint32_t)(1)) +/** CAN Transmit Interrupt 1 */ +#define CAN_ICR_TI1 ((uint32_t)(1<<1)) +/** CAN Error Warning Interrupt */ +#define CAN_ICR_EI ((uint32_t)(1<<2)) +/** CAN Data Overrun Interrupt */ +#define CAN_ICR_DOI ((uint32_t)(1<<3)) +/** CAN Wake-Up Interrupt */ +#define CAN_ICR_WUI ((uint32_t)(1<<4)) +/** CAN Error Passive Interrupt */ +#define CAN_ICR_EPI ((uint32_t)(1<<5)) +/** CAN Arbitration Lost Interrupt */ +#define CAN_ICR_ALI ((uint32_t)(1<<6)) +/** CAN Bus Error Interrupt */ +#define CAN_ICR_BEI ((uint32_t)(1<<7)) +/** CAN ID Ready Interrupt */ +#define CAN_ICR_IDI ((uint32_t)(1<<8)) +/** CAN Transmit Interrupt 2 */ +#define CAN_ICR_TI2 ((uint32_t)(1<<9)) +/** CAN Transmit Interrupt 3 */ +#define CAN_ICR_TI3 ((uint32_t)(1<<10)) +/** CAN Error Code Capture */ +#define CAN_ICR_ERRBIT(n) ((uint32_t)((n&0x1F)<<16)) +/** CAN Error Direction */ +#define CAN_ICR_ERRDIR ((uint32_t)(1<<21)) +/** CAN Error Capture */ +#define CAN_ICR_ERRC(n) ((uint32_t)((n&0x3)<<22)) +/** CAN Arbitration Lost Capture */ +#define CAN_ICR_ALCBIT(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Interrupt Enable Register + **********************************************************************/ +/** CAN Receive Interrupt Enable */ +#define CAN_IER_RIE ((uint32_t)(1)) +/** CAN Transmit Interrupt Enable for buffer 1 */ +#define CAN_IER_TIE1 ((uint32_t)(1<<1)) +/** CAN Error Warning Interrupt Enable */ +#define CAN_IER_EIE ((uint32_t)(1<<2)) +/** CAN Data Overrun Interrupt Enable */ +#define CAN_IER_DOIE ((uint32_t)(1<<3)) +/** CAN Wake-Up Interrupt Enable */ +#define CAN_IER_WUIE ((uint32_t)(1<<4)) +/** CAN Error Passive Interrupt Enable */ +#define CAN_IER_EPIE ((uint32_t)(1<<5)) +/** CAN Arbitration Lost Interrupt Enable */ +#define CAN_IER_ALIE ((uint32_t)(1<<6)) +/** CAN Bus Error Interrupt Enable */ +#define CAN_IER_BEIE ((uint32_t)(1<<7)) +/** CAN ID Ready Interrupt Enable */ +#define CAN_IER_IDIE ((uint32_t)(1<<8)) +/** CAN Transmit Enable Interrupt for Buffer 2 */ +#define CAN_IER_TIE2 ((uint32_t)(1<<9)) +/** CAN Transmit Enable Interrupt for Buffer 3 */ +#define CAN_IER_TIE3 ((uint32_t)(1<<10)) + +/*********************************************************************//** + * Macro defines for CAN Bus Timing Register + **********************************************************************/ +/** CAN Baudrate Prescaler */ +#define CAN_BTR_BRP(n) ((uint32_t)(n&0x3FF)) +/** CAN Synchronization Jump Width */ +#define CAN_BTR_SJM(n) ((uint32_t)((n&0x3)<<14)) +/** CAN Time Segment 1 */ +#define CAN_BTR_TESG1(n) ((uint32_t)(n&0xF)<<16)) +/** CAN Time Segment 2 */ +#define CAN_BTR_TESG2(n) ((uint32_t)(n&0xF)<<20)) +/** CAN Sampling */ +#define CAN_BTR_SAM(n) ((uint32_t)(1<<23)) + +/*********************************************************************//** + * Macro defines for CAN Error Warning Limit Register + **********************************************************************/ +/** CAN Error Warning Limit */ +#define CAN_EWL_EWL(n) ((uint32_t)(n&0xFF)) + +/*********************************************************************//** + * Macro defines for CAN Status Register + **********************************************************************/ +/** CAN Receive Buffer Status */ +#define CAN_SR_RBS ((uint32_t)(1)) +/** CAN Data Overrun Status */ +#define CAN_SR_DOS ((uint32_t)(1<<1)) +/** CAN Transmit Buffer Status 1 */ +#define CAN_SR_TBS1 ((uint32_t)(1<<2)) +/** CAN Transmission Complete Status of Buffer 1 */ +#define CAN_SR_TCS1 ((uint32_t)(1<<3)) +/** CAN Receive Status */ +#define CAN_SR_RS ((uint32_t)(1<<4)) +/** CAN Transmit Status 1 */ +#define CAN_SR_TS1 ((uint32_t)(1<<5)) +/** CAN Error Status */ +#define CAN_SR_ES ((uint32_t)(1<<6)) +/** CAN Bus Status */ +#define CAN_SR_BS ((uint32_t)(1<<7)) +/** CAN Transmit Buffer Status 2 */ +#define CAN_SR_TBS2 ((uint32_t)(1<<10)) +/** CAN Transmission Complete Status of Buffer 2 */ +#define CAN_SR_TCS2 ((uint32_t)(1<<11)) +/** CAN Transmit Status 2 */ +#define CAN_SR_TS2 ((uint32_t)(1<<13)) +/** CAN Transmit Buffer Status 2 */ +#define CAN_SR_TBS3 ((uint32_t)(1<<18)) +/** CAN Transmission Complete Status of Buffer 2 */ +#define CAN_SR_TCS3 ((uint32_t)(1<<19)) +/** CAN Transmit Status 2 */ +#define CAN_SR_TS3 ((uint32_t)(1<<21)) + +/*********************************************************************//** + * Macro defines for CAN Receive Frame Status Register + **********************************************************************/ +/** CAN ID Index */ +#define CAN_RFS_ID_INDEX(n) ((uint32_t)(n&0x3FF)) +/** CAN Bypass */ +#define CAN_RFS_BP ((uint32_t)(1<<10)) +/** CAN Data Length Code */ +#define CAN_RFS_DLC(n) ((uint32_t)((n&0xF)<<16) +/** CAN Remote Transmission Request */ +#define CAN_RFS_RTR ((uint32_t)(1<<30)) +/** CAN control 11 bit or 29 bit Identifier */ +#define CAN_RFS_FF ((uint32_t)(1<<31)) + +/*********************************************************************//** + * Macro defines for CAN Receive Identifier Register + **********************************************************************/ +/** CAN 11 bit Identifier */ +#define CAN_RID_ID_11(n) ((uint32_t)(n&0x7FF)) +/** CAN 29 bit Identifier */ +#define CAN_RID_ID_29(n) ((uint32_t)(n&0x1FFFFFFF)) + +/*********************************************************************//** + * Macro defines for CAN Receive Data A Register + **********************************************************************/ +/** CAN Receive Data 1 */ +#define CAN_RDA_DATA1(n) ((uint32_t)(n&0xFF)) +/** CAN Receive Data 2 */ +#define CAN_RDA_DATA2(n) ((uint32_t)((n&0xFF)<<8)) +/** CAN Receive Data 3 */ +#define CAN_RDA_DATA3(n) ((uint32_t)((n&0xFF)<<16)) +/** CAN Receive Data 4 */ +#define CAN_RDA_DATA4(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Receive Data B Register + **********************************************************************/ +/** CAN Receive Data 5 */ +#define CAN_RDB_DATA5(n) ((uint32_t)(n&0xFF)) +/** CAN Receive Data 6 */ +#define CAN_RDB_DATA6(n) ((uint32_t)((n&0xFF)<<8)) +/** CAN Receive Data 7 */ +#define CAN_RDB_DATA7(n) ((uint32_t)((n&0xFF)<<16)) +/** CAN Receive Data 8 */ +#define CAN_RDB_DATA8(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Frame Information Register + **********************************************************************/ +/** CAN Priority */ +#define CAN_TFI_PRIO(n) ((uint32_t)(n&0xFF)) +/** CAN Data Length Code */ +#define CAN_TFI_DLC(n) ((uint32_t)((n&0xF)<<16)) +/** CAN Remote Frame Transmission */ +#define CAN_TFI_RTR ((uint32_t)(1<<30)) +/** CAN control 11-bit or 29-bit Identifier */ +#define CAN_TFI_FF ((uint32_t)(1<<31)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Identifier Register + **********************************************************************/ +/** CAN 11-bit Identifier */ +#define CAN_TID_ID11(n) ((uint32_t)(n&0x7FF)) +/** CAN 11-bit Identifier */ +#define CAN_TID_ID29(n) ((uint32_t)(n&0x1FFFFFFF)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Data A Register + **********************************************************************/ +/** CAN Transmit Data 1 */ +#define CAN_TDA_DATA1(n) ((uint32_t)(n&0xFF)) +/** CAN Transmit Data 2 */ +#define CAN_TDA_DATA2(n) ((uint32_t)((n&0xFF)<<8)) +/** CAN Transmit Data 3 */ +#define CAN_TDA_DATA3(n) ((uint32_t)((n&0xFF)<<16)) +/** CAN Transmit Data 4 */ +#define CAN_TDA_DATA4(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Transmit Data B Register + **********************************************************************/ +/** CAN Transmit Data 5 */ +#define CAN_TDA_DATA5(n) ((uint32_t)(n&0xFF)) +/** CAN Transmit Data 6 */ +#define CAN_TDA_DATA6(n) ((uint32_t)((n&0xFF)<<8)) +/** CAN Transmit Data 7 */ +#define CAN_TDA_DATA7(n) ((uint32_t)((n&0xFF)<<16)) +/** CAN Transmit Data 8 */ +#define CAN_TDA_DATA8(n) ((uint32_t)((n&0xFF)<<24)) + +/*********************************************************************//** + * Macro defines for CAN Sleep Clear Register + **********************************************************************/ +/** CAN1 Sleep mode */ +#define CAN1SLEEPCLR ((uint32_t)(1<<1)) +/** CAN2 Sleep Mode */ +#define CAN2SLEEPCLR ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for CAN Wake up Flags Register + **********************************************************************/ +/** CAN1 Sleep mode */ +#define CAN_WAKEFLAGES_CAN1WAKE ((uint32_t)(1<<1)) +/** CAN2 Sleep Mode */ +#define CAN_WAKEFLAGES_CAN2WAKE ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for Central transmit Status Register + **********************************************************************/ +/** CAN Transmit 1 */ +#define CAN_TSR_TS1 ((uint32_t)(1)) +/** CAN Transmit 2 */ +#define CAN_TSR_TS2 ((uint32_t)(1<<1)) +/** CAN Transmit Buffer Status 1 */ +#define CAN_TSR_TBS1 ((uint32_t)(1<<8)) +/** CAN Transmit Buffer Status 2 */ +#define CAN_TSR_TBS2 ((uint32_t)(1<<9)) +/** CAN Transmission Complete Status 1 */ +#define CAN_TSR_TCS1 ((uint32_t)(1<<16)) +/** CAN Transmission Complete Status 2 */ +#define CAN_TSR_TCS2 ((uint32_t)(1<<17)) + +/*********************************************************************//** + * Macro defines for Central Receive Status Register + **********************************************************************/ +/** CAN Receive Status 1 */ +#define CAN_RSR_RS1 ((uint32_t)(1)) +/** CAN Receive Status 1 */ +#define CAN_RSR_RS2 ((uint32_t)(1<<1)) +/** CAN Receive Buffer Status 1*/ +#define CAN_RSR_RB1 ((uint32_t)(1<<8)) +/** CAN Receive Buffer Status 2*/ +#define CAN_RSR_RB2 ((uint32_t)(1<<9)) +/** CAN Data Overrun Status 1 */ +#define CAN_RSR_DOS1 ((uint32_t)(1<<16)) +/** CAN Data Overrun Status 1 */ +#define CAN_RSR_DOS2 ((uint32_t)(1<<17)) + +/*********************************************************************//** + * Macro defines for Central Miscellaneous Status Register + **********************************************************************/ +/** Same CAN Error Status in CAN1GSR */ +#define CAN_MSR_E1 ((uint32_t)(1)) +/** Same CAN Error Status in CAN2GSR */ +#define CAN_MSR_E2 ((uint32_t)(1<<1)) +/** Same CAN Bus Status in CAN1GSR */ +#define CAN_MSR_BS1 ((uint32_t)(1<<8)) +/** Same CAN Bus Status in CAN2GSR */ +#define CAN_MSR_BS2 ((uint32_t)(1<<9)) + +/*********************************************************************//** + * Macro defines for Acceptance Filter Mode Register + **********************************************************************/ +/** CAN Acceptance Filter Off mode */ +#define CAN_AFMR_AccOff ((uint32_t)(1)) +/** CAN Acceptance File Bypass mode */ +#define CAN_AFMR_AccBP ((uint32_t)(1<<1)) +/** FullCAN Mode Enhancements */ +#define CAN_AFMR_eFCAN ((uint32_t)(1<<2)) + +/*********************************************************************//** + * Macro defines for Standard Frame Individual Start Address Register + **********************************************************************/ +/** The start address of the table of individual Standard Identifier */ +#define CAN_STT_sa(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for Standard Frame Group Start Address Register + **********************************************************************/ +/** The start address of the table of grouped Standard Identifier */ +#define CAN_SFF_GRP_sa(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for Extended Frame Start Address Register + **********************************************************************/ +/** The start address of the table of individual Extended Identifier */ +#define CAN_EFF_sa(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for Extended Frame Group Start Address Register + **********************************************************************/ +/** The start address of the table of grouped Extended Identifier */ +#define CAN_Eff_GRP_sa(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for End Of AF Table Register + **********************************************************************/ +/** The End of Table of AF LookUp Table */ +#define CAN_EndofTable(n) ((uint32_t)((n&3FF)<<2)) + +/*********************************************************************//** + * Macro defines for LUT Error Address Register + **********************************************************************/ +/** CAN Look-Up Table Error Address */ +#define CAN_LUTerrAd(n) ((uint32_t)((n&1FF)<<2)) + +/*********************************************************************//** + * Macro defines for LUT Error Register + **********************************************************************/ +/** CAN Look-Up Table Error */ +#define CAN_LUTerr ((uint32_t)(1)) + +/*********************************************************************//** + * Macro defines for Global FullCANInterrupt Enable Register + **********************************************************************/ +/** Global FullCANInterrupt Enable */ +#define CAN_FCANIE ((uint32_t)(1)) + +/*********************************************************************//** + * Macro defines for FullCAN Interrupt and Capture Register 0 + **********************************************************************/ +/** FullCAN Interrupt and Capture (0-31)*/ +#define CAN_FCANIC0_IntPnd(n) ((uint32_t)(1<<n)) + +/*********************************************************************//** + * Macro defines for FullCAN Interrupt and Capture Register 1 + **********************************************************************/ +/** FullCAN Interrupt and Capture (0-31)*/ +#define CAN_FCANIC1_IntPnd(n) ((uint32_t)(1<<(n-32))) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid CAN peripheral or not */ +#define PARAM_CANx(x) ((((uint32_t*)x)==((uint32_t *)LPC_CAN1)) \ +||(((uint32_t*)x)==((uint32_t *)LPC_CAN2))) + +/* Macro to determine if it is valid CANAF or not*/ +#define PARAM_CANAFx(x) (((uint32_t*)x)== ((uint32_t*)LPC_CANAF)) + +/* Macro to determine if it is valid CANAF RAM or not*/ +#define PARAM_CANAFRAMx(x) (((uint32_t*)x)== (uint32_t*)LPC_CANAF_RAM) + +/* Macro to determine if it is valid CANCR or not*/ +#define PARAM_CANCRx(x) (((uint32_t*)x)==((uint32_t*)LPC_CANCR)) + +/** Macro to check Data to send valid */ +#define PARAM_I2S_DATA(data) ((data>=0)&&(data <= 0xFFFFFFFF)) + +/** Macro to check frequency value */ +#define PRAM_I2S_FREQ(freq) ((freq>=16000)&&(freq <= 96000)) + +/** Macro to check Frame Identifier */ +#define PARAM_ID_11(n) ((n>>11)==0) /*-- 11 bit --*/ +#define PARAM_ID_29(n) ((n>>29)==0) /*-- 29 bit --*/ + +/** Macro to check DLC value */ +#define PARAM_DLC(n) ((n>>4)==0) /*-- 4 bit --*/ +/** Macro to check ID format type */ +#define PARAM_ID_FORMAT(n) ((n==STD_ID_FORMAT)||(n==EXT_ID_FORMAT)) + +/** Macro to check Group identifier */ +#define PARAM_GRP_ID(x, y) ((x<=y)) + +/** Macro to check Frame type */ +#define PARAM_FRAME_TYPE(n) ((n==DATA_FRAME)||(n==REMOTE_FRAME)) + +/** Macro to check Control/Central Status type parameter */ +#define PARAM_CTRL_STS_TYPE(n) ((n==CANCTRL_GLOBAL_STS)||(n==CANCTRL_INT_CAP) \ +||(n==CANCTRL_ERR_WRN)||(n==CANCTRL_STS)) + +/** Macro to check CR status type */ +#define PARAM_CR_STS_TYPE(n) ((n==CANCR_TX_STS)||(n==CANCR_RX_STS) \ +||(n==CANCR_MS)) +/** Macro to check AF Mode type parameter */ +#define PARAM_AFMODE_TYPE(n) ((n==CAN_Normal)||(n==CAN_AccOff) \ +||(n==CAN_AccBP)||(n==CAN_eFCAN)) + +/** Macro to check Operation Mode */ +#define PARAM_MODE_TYPE(n) ((n==CAN_OPERATING_MODE)||(n==CAN_RESET_MODE) \ +||(n==CAN_LISTENONLY_MODE)||(n==CAN_SELFTEST_MODE) \ +||(n==CAN_TXPRIORITY_MODE)||(n==CAN_SLEEP_MODE) \ +||(n==CAN_RXPOLARITY_MODE)||(n==CAN_TEST_MODE)) + +/** Macro define for struct AF_Section parameter */ +#define PARAM_CTRL(n) ((n==CAN1_CTRL)|(n==CAN2_CTRL)) + +/** Macro define for struct AF_Section parameter */ +#define PARAM_MSG_DISABLE(n) ((n==MSG_ENABLE)|(n==MSG_DISABLE)) + +/**Macro to check Interrupt Type parameter */ +#define PARAM_INT_EN_TYPE(n) ((n==CANINT_RIE)||(n==CANINT_TIE1) \ +||(n==CANINT_EIE)||(n==CANINT_DOIE) \ +||(n==CANINT_WUIE)||(n==CANINT_EPIE) \ +||(n==CANINT_ALIE)||(n==CANINT_BEIE) \ +||(n==CANINT_IDIE)||(n==CANINT_TIE2) \ +||(n==CANINT_TIE3)||(n==CANINT_FCE)) + +/** Macro to check AFLUT Entry type */ +#define PARAM_AFLUT_ENTRY_TYPE(n) ((n==FULLCAN_ENTRY)||(n==EXPLICIT_STANDARD_ENTRY)\ +||(n==GROUP_STANDARD_ENTRY)||(n==EXPLICIT_EXTEND_ENTRY) \ +||(n==GROUP_EXTEND_ENTRY)) + +/** Macro to check position */ +#define PARAM_POSITION(n) ((n)<512) + +/** + * @} + */ + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup CAN_Public_Types CAN Public Types + * @{ + */ + +/** CAN configuration structure */ +/*********************************************************************** + * CAN device configuration commands (IOCTL commands and arguments) + **********************************************************************/ +/** + * @brief CAN ID format definition + */ +typedef enum { + STD_ID_FORMAT = 0, /**< Use standard ID format (11 bit ID) */ + EXT_ID_FORMAT = 1 /**< Use extended ID format (29 bit ID) */ +} CAN_ID_FORMAT_Type; + +/** + * @brief AFLUT Entry type definition + */ +typedef enum { + FULLCAN_ENTRY = 0, + EXPLICIT_STANDARD_ENTRY, + GROUP_STANDARD_ENTRY, + EXPLICIT_EXTEND_ENTRY, + GROUP_EXTEND_ENTRY, +} AFLUT_ENTRY_Type; + +/** + * @brief Symbolic names for type of CAN message + */ +typedef enum { + DATA_FRAME = 0, /**< Data frame */ + REMOTE_FRAME = 1 /**< Remote frame */ +} CAN_FRAME_Type; + +/** + * @brief CAN Control status definition + */ +typedef enum { + CANCTRL_GLOBAL_STS = 0, /**< CAN Global Status */ + CANCTRL_INT_CAP, /**< CAN Interrupt and Capture */ + CANCTRL_ERR_WRN, /**< CAN Error Warning Limit */ + CANCTRL_STS /**< CAN Control Status */ +} CAN_CTRL_STS_Type; + +/** + * @brief Central CAN status type definition + */ +typedef enum { + CANCR_TX_STS = 0, /**< Central CAN Tx Status */ + CANCR_RX_STS, /**< Central CAN Rx Status */ + CANCR_MS /**< Central CAN Miscellaneous Status */ +} CAN_CR_STS_Type; + +/** + * @brief FullCAN Interrupt Capture type definition + */ +typedef enum{ + FULLCAN_IC0, /**< FullCAN Interrupt and Capture 0 */ + FULLCAN_IC1 /**< FullCAN Interrupt and Capture 1 */ +}FullCAN_IC_Type; + +/** + * @brief CAN interrupt enable type definition + */ +typedef enum { + CANINT_RIE = 0, /**< CAN Receiver Interrupt Enable */ + CANINT_TIE1, /**< CAN Transmit Interrupt Enable */ + CANINT_EIE, /**< CAN Error Warning Interrupt Enable */ + CANINT_DOIE, /**< CAN Data Overrun Interrupt Enable */ + CANINT_WUIE, /**< CAN Wake-Up Interrupt Enable */ + CANINT_EPIE, /**< CAN Error Passive Interrupt Enable */ + CANINT_ALIE, /**< CAN Arbitration Lost Interrupt Enable */ + CANINT_BEIE, /**< CAN Bus Error Inter rupt Enable */ + CANINT_IDIE, /**< CAN ID Ready Interrupt Enable */ + CANINT_TIE2, /**< CAN Transmit Interrupt Enable for Buffer2 */ + CANINT_TIE3, /**< CAN Transmit Interrupt Enable for Buffer3 */ + CANINT_FCE /**< FullCAN Interrupt Enable */ +} CAN_INT_EN_Type; + +/** + * @brief Acceptance Filter Mode type definition + */ +typedef enum { + CAN_Normal = 0, /**< Normal Mode */ + CAN_AccOff, /**< Acceptance Filter Off Mode */ + CAN_AccBP, /**< Acceptance Fileter Bypass Mode */ + CAN_eFCAN /**< FullCAN Mode Enhancement */ +} CAN_AFMODE_Type; + +/** + * @brief CAN Mode Type definition + */ +typedef enum { + CAN_OPERATING_MODE = 0, /**< Operating Mode */ + CAN_RESET_MODE, /**< Reset Mode */ + CAN_LISTENONLY_MODE, /**< Listen Only Mode */ + CAN_SELFTEST_MODE, /**< Seft Test Mode */ + CAN_TXPRIORITY_MODE, /**< Transmit Priority Mode */ + CAN_SLEEP_MODE, /**< Sleep Mode */ + CAN_RXPOLARITY_MODE, /**< Receive Polarity Mode */ + CAN_TEST_MODE /**< Test Mode */ +} CAN_MODE_Type; + +/** + * @brief Error values that functions can return + */ +typedef enum { + CAN_OK = 1, /**< No error */ + CAN_OBJECTS_FULL_ERROR, /**< No more rx or tx objects available */ + CAN_FULL_OBJ_NOT_RCV, /**< Full CAN object not received */ + CAN_NO_RECEIVE_DATA, /**< No have receive data available */ + CAN_AF_ENTRY_ERROR, /**< Entry load in AFLUT is unvalid */ + CAN_CONFLICT_ID_ERROR, /**< Conflict ID occur */ + CAN_ENTRY_NOT_EXIT_ERROR /**< Entry remove outo AFLUT is not exit */ +} CAN_ERROR; + +/** + * @brief Pin Configuration structure + */ +typedef struct { + uint8_t RD; /**< Serial Inputs, from CAN transceivers, should be: + ** For CAN1: + - CAN_RD1_P0_0: RD pin is on P0.0 + - CAN_RD1_P0_21 : RD pin is on P0.21 + ** For CAN2: + - CAN_RD2_P0_4: RD pin is on P0.4 + - CAN_RD2_P2_7: RD pin is on P2.7 + */ + uint8_t TD; /**< Serial Outputs, To CAN transceivers, should be: + ** For CAN1: + - CAN_TD1_P0_1: TD pin is on P0.1 + - CAN_TD1_P0_22: TD pin is on P0.22 + ** For CAN2: + - CAN_TD2_P0_5: TD pin is on P0.5 + - CAN_TD2_P2_8: TD pin is on P2.8 + */ +} CAN_PinCFG_Type; + +/** + * @brief CAN message object structure + */ +typedef struct { + uint32_t id; /**< 29 bit identifier, it depend on "format" value + - if format = STD_ID_FORMAT, id should be 11 bit identifier + - if format = EXT_ID_FORMAT, id should be 29 bit identifier + */ + uint8_t dataA[4]; /**< Data field A */ + uint8_t dataB[4]; /**< Data field B */ + uint8_t len; /**< Length of data field in bytes, should be: + - 0000b-0111b: 0-7 bytes + - 1xxxb: 8 bytes + */ + uint8_t format; /**< Identifier Format, should be: + - STD_ID_FORMAT: Standard ID - 11 bit format + - EXT_ID_FORMAT: Extended ID - 29 bit format + */ + uint8_t type; /**< Remote Frame transmission, should be: + - DATA_FRAME: the number of data bytes called out by the DLC + field are send from the CANxTDA and CANxTDB registers + - REMOTE_FRAME: Remote Frame is sent + */ +} CAN_MSG_Type; + +/** + * @brief FullCAN Entry structure + */ +typedef struct { + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable; /**< Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t id_11; /**< Standard ID, should be 11-bit value */ +} FullCAN_Entry; + +/** + * @brief Standard ID Frame Format Entry structure + */ +typedef struct { + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable; /**< Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t id_11; /**< Standard ID, should be 11-bit value */ +} SFF_Entry; + +/** + * @brief Group of Standard ID Frame Format Entry structure + */ +typedef struct { + uint8_t controller1; /**< First CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable1; /**< First Disable bit, should be: + - MSG_ENABLE: disable bit = 0) + - MSG_DISABLE: disable bit = 1 + */ + uint16_t lowerID; /**< ID lower bound, should be 11-bit value */ + uint8_t controller2; /**< Second CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t disable2; /**< Second Disable bit, should be: + - MSG_ENABLE: disable bit = 0 + - MSG_DISABLE: disable bit = 1 + */ + uint16_t upperID; /**< ID upper bound, should be 11-bit value and + equal or greater than lowerID + */ +} SFF_GPR_Entry; + +/** + * @brief Extended ID Frame Format Entry structure + */ +typedef struct { + uint8_t controller; /**< CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint32_t ID_29; /**< Extend ID, shoud be 29-bit value */ +} EFF_Entry; + + +/** + * @brief Group of Extended ID Frame Format Entry structure + */ +typedef struct { + uint8_t controller1; /**< First CAN Controller, should be: + - CAN1_CTRL: CAN1 Controller + - CAN2_CTRL: CAN2 Controller + */ + uint8_t controller2; /**< Second Disable bit, should be: + - MSG_ENABLE: disable bit = 0(default) + - MSG_DISABLE: disable bit = 1 + */ + uint32_t lowerEID; /**< Extended ID lower bound, should be 29-bit value */ + uint32_t upperEID; /**< Extended ID upper bound, should be 29-bit value */ +} EFF_GPR_Entry; + + +/** + * @brief Acceptance Filter Section Table structure + */ +typedef struct { + FullCAN_Entry* FullCAN_Sec; /**< The pointer point to FullCAN_Entry */ + uint8_t FC_NumEntry; /**< FullCAN Entry Number */ + SFF_Entry* SFF_Sec; /**< The pointer point to SFF_Entry */ + uint8_t SFF_NumEntry; /**< Standard ID Entry Number */ + SFF_GPR_Entry* SFF_GPR_Sec; /**< The pointer point to SFF_GPR_Entry */ + uint8_t SFF_GPR_NumEntry; /**< Group Standard ID Entry Number */ + EFF_Entry* EFF_Sec; /**< The pointer point to EFF_Entry */ + uint8_t EFF_NumEntry; /**< Extended ID Entry Number */ + EFF_GPR_Entry* EFF_GPR_Sec; /**< The pointer point to EFF_GPR_Entry */ + uint8_t EFF_GPR_NumEntry; /**< Group Extended ID Entry Number */ +} AF_SectionDef; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup CAN_Public_Functions CAN Public Functions + * @{ + */ + +/* Init/DeInit CAN peripheral -----------*/ +void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate); +void CAN_DeInit(LPC_CAN_TypeDef *CANx); + +/* CAN messages functions ---------------*/ +Status CAN_SendMsg(LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg); +Status CAN_ReceiveMsg(LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg); +CAN_ERROR FCAN_ReadObj(LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg); + +/* CAN configure functions ---------------*/ +void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, + FunctionalState NewState); +void CAN_SetAFMode(LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFmode); +void CAN_SetCommand(LPC_CAN_TypeDef* CANx, uint32_t CMRType); + +/* AFLUT functions ---------------------- */ +CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection); +CAN_ERROR CAN_LoadFullCANEntry(LPC_CAN_TypeDef* CANx, uint16_t ID); +CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t ID, + CAN_ID_FORMAT_Type format); +CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, + uint32_t upperID, CAN_ID_FORMAT_Type format); +CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position); + +/* CAN interrupt functions -----------------*/ +void CAN_IRQCmd(LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState); +uint32_t CAN_IntGetStatus(LPC_CAN_TypeDef* CANx); + +/* CAN get status functions ----------------*/ +IntStatus CAN_FullCANIntGetStatus (LPC_CANAF_TypeDef* CANAFx); +uint32_t CAN_FullCANPendGetStatus (LPC_CANAF_TypeDef* CANAFx, FullCAN_IC_Type type); +uint32_t CAN_GetCTRLStatus(LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg); +uint32_t CAN_GetCRStatus(LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_CAN_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_clkpwr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_clkpwr.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,338 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = 0x8; + /* 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 = 0x09; + /* 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_clkpwr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_clkpwr.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,394 @@ +/***********************************************************************//** + * @file lpc17xx_clkpwr.h + * @brief Contains all macro definitions and function prototypes + * support for Clock and Power Control firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup CLKPWR CLKPWR + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_CLKPWR_H_ +#define LPC17XX_CLKPWR_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup CLKPWR_Public_Macros CLKPWR Public Macros + * @{ + */ + +/********************************************************************** + * Peripheral Clock Selection Definitions + **********************************************************************/ +/** Peripheral clock divider bit position for WDT */ +#define CLKPWR_PCLKSEL_WDT ((uint32_t)(0)) +/** Peripheral clock divider bit position for TIMER0 */ +#define CLKPWR_PCLKSEL_TIMER0 ((uint32_t)(2)) +/** Peripheral clock divider bit position for TIMER1 */ +#define CLKPWR_PCLKSEL_TIMER1 ((uint32_t)(4)) +/** Peripheral clock divider bit position for UART0 */ +#define CLKPWR_PCLKSEL_UART0 ((uint32_t)(6)) +/** Peripheral clock divider bit position for UART1 */ +#define CLKPWR_PCLKSEL_UART1 ((uint32_t)(8)) +/** Peripheral clock divider bit position for PWM1 */ +#define CLKPWR_PCLKSEL_PWM1 ((uint32_t)(12)) +/** Peripheral clock divider bit position for I2C0 */ +#define CLKPWR_PCLKSEL_I2C0 ((uint32_t)(14)) +/** Peripheral clock divider bit position for SPI */ +#define CLKPWR_PCLKSEL_SPI ((uint32_t)(16)) +/** Peripheral clock divider bit position for SSP1 */ +#define CLKPWR_PCLKSEL_SSP1 ((uint32_t)(20)) +/** Peripheral clock divider bit position for DAC */ +#define CLKPWR_PCLKSEL_DAC ((uint32_t)(22)) +/** Peripheral clock divider bit position for ADC */ +#define CLKPWR_PCLKSEL_ADC ((uint32_t)(24)) +/** Peripheral clock divider bit position for CAN1 */ +#define CLKPWR_PCLKSEL_CAN1 ((uint32_t)(26)) +/** Peripheral clock divider bit position for CAN2 */ +#define CLKPWR_PCLKSEL_CAN2 ((uint32_t)(28)) +/** Peripheral clock divider bit position for ACF */ +#define CLKPWR_PCLKSEL_ACF ((uint32_t)(30)) +/** Peripheral clock divider bit position for QEI */ +#define CLKPWR_PCLKSEL_QEI ((uint32_t)(32)) +/** Peripheral clock divider bit position for PCB */ +#define CLKPWR_PCLKSEL_PCB ((uint32_t)(36)) +/** Peripheral clock divider bit position for I2C1 */ +#define CLKPWR_PCLKSEL_I2C1 ((uint32_t)(38)) +/** Peripheral clock divider bit position for SSP0 */ +#define CLKPWR_PCLKSEL_SSP0 ((uint32_t)(42)) +/** Peripheral clock divider bit position for TIMER2 */ +#define CLKPWR_PCLKSEL_TIMER2 ((uint32_t)(44)) +/** Peripheral clock divider bit position for TIMER3 */ +#define CLKPWR_PCLKSEL_TIMER3 ((uint32_t)(46)) +/** Peripheral clock divider bit position for UART2 */ +#define CLKPWR_PCLKSEL_UART2 ((uint32_t)(48)) +/** Peripheral clock divider bit position for UART3 */ +#define CLKPWR_PCLKSEL_UART3 ((uint32_t)(50)) +/** Peripheral clock divider bit position for I2C2 */ +#define CLKPWR_PCLKSEL_I2C2 ((uint32_t)(52)) +/** Peripheral clock divider bit position for I2S */ +#define CLKPWR_PCLKSEL_I2S ((uint32_t)(54)) +/** Peripheral clock divider bit position for RIT */ +#define CLKPWR_PCLKSEL_RIT ((uint32_t)(58)) +/** Peripheral clock divider bit position for SYSCON */ +#define CLKPWR_PCLKSEL_SYSCON ((uint32_t)(60)) +/** Peripheral clock divider bit position for MC */ +#define CLKPWR_PCLKSEL_MC ((uint32_t)(62)) + +/** Macro for Peripheral Clock Selection register bit values + * Note: When CCLK_DIV_8, Peripheral�s clock is selected to + * PCLK_xyz = CCLK/8 except for CAN1, CAN2, and CAN filtering + * when �11�selects PCLK_xyz = CCLK/6 */ +/* Peripheral clock divider is set to 4 from CCLK */ +#define CLKPWR_PCLKSEL_CCLK_DIV_4 ((uint32_t)(0)) +/** Peripheral clock divider is the same with CCLK */ +#define CLKPWR_PCLKSEL_CCLK_DIV_1 ((uint32_t)(1)) +/** Peripheral clock divider is set to 2 from CCLK */ +#define CLKPWR_PCLKSEL_CCLK_DIV_2 ((uint32_t)(2)) + + +/******************************************************************** +* Power Control for Peripherals Definitions +**********************************************************************/ +/** Timer/Counter 0 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM0 ((uint32_t)(1<<1)) +/* Timer/Counter 1 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM1 ((uint32_t)(1<<2)) +/** UART0 power/clock control bit */ +#define CLKPWR_PCONP_PCUART0 ((uint32_t)(1<<3)) +/** UART1 power/clock control bit */ +#define CLKPWR_PCONP_PCUART1 ((uint32_t)(1<<4)) +/** PWM1 power/clock control bit */ +#define CLKPWR_PCONP_PCPWM1 ((uint32_t)(1<<6)) +/** The I2C0 interface power/clock control bit */ +#define CLKPWR_PCONP_PCI2C0 ((uint32_t)(1<<7)) +/** The SPI interface power/clock control bit */ +#define CLKPWR_PCONP_PCSPI ((uint32_t)(1<<8)) +/** The RTC power/clock control bit */ +#define CLKPWR_PCONP_PCRTC ((uint32_t)(1<<9)) +/** The SSP1 interface power/clock control bit */ +#define CLKPWR_PCONP_PCSSP1 ((uint32_t)(1<<10)) +/** A/D converter 0 (ADC0) power/clock control bit */ +#define CLKPWR_PCONP_PCAD ((uint32_t)(1<<12)) +/** CAN Controller 1 power/clock control bit */ +#define CLKPWR_PCONP_PCAN1 ((uint32_t)(1<<13)) +/** CAN Controller 2 power/clock control bit */ +#define CLKPWR_PCONP_PCAN2 ((uint32_t)(1<<14)) +/** GPIO power/clock control bit */ +#define CLKPWR_PCONP_PCGPIO ((uint32_t)(1<<15)) +/** Repetitive Interrupt Timer power/clock control bit */ +#define CLKPWR_PCONP_PCRIT ((uint32_t)(1<<16)) +/** Motor Control PWM */ +#define CLKPWR_PCONP_PCMC ((uint32_t)(1<<17)) +/** Quadrature Encoder Interface power/clock control bit */ +#define CLKPWR_PCONP_PCQEI ((uint32_t)(1<<18)) +/** The I2C1 interface power/clock control bit */ +#define CLKPWR_PCONP_PCI2C1 ((uint32_t)(1<<19)) +/** The SSP0 interface power/clock control bit */ +#define CLKPWR_PCONP_PCSSP0 ((uint32_t)(1<<21)) +/** Timer 2 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM2 ((uint32_t)(1<<22)) +/** Timer 3 power/clock control bit */ +#define CLKPWR_PCONP_PCTIM3 ((uint32_t)(1<<23)) +/** UART 2 power/clock control bit */ +#define CLKPWR_PCONP_PCUART2 ((uint32_t)(1<<24)) +/** UART 3 power/clock control bit */ +#define CLKPWR_PCONP_PCUART3 ((uint32_t)(1<<25)) +/** I2C interface 2 power/clock control bit */ +#define CLKPWR_PCONP_PCI2C2 ((uint32_t)(1<<26)) +/** I2S interface power/clock control bit*/ +#define CLKPWR_PCONP_PCI2S ((uint32_t)(1<<27)) +/** GP DMA function power/clock control bit*/ +#define CLKPWR_PCONP_PCGPDMA ((uint32_t)(1<<29)) +/** Ethernet block power/clock control bit*/ +#define CLKPWR_PCONP_PCENET ((uint32_t)(1<<30)) +/** USB interface power/clock control bit*/ +#define CLKPWR_PCONP_PCUSB ((uint32_t)(1<<31)) + + +/** + * @} + */ +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup CLKPWR_Private_Macros CLKPWR Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for Clock Source Select Register + **********************************************************************/ +/** Internal RC oscillator */ +#define CLKPWR_CLKSRCSEL_CLKSRC_IRC ((uint32_t)(0x00)) +/** Main oscillator */ +#define CLKPWR_CLKSRCSEL_CLKSRC_MAINOSC ((uint32_t)(0x01)) +/** RTC oscillator */ +#define CLKPWR_CLKSRCSEL_CLKSRC_RTC ((uint32_t)(0x02)) +/** Clock source selection bit mask */ +#define CLKPWR_CLKSRCSEL_BITMASK ((uint32_t)(0x03)) + +/*********************************************************************//** + * Macro defines for Clock Output Configuration Register + **********************************************************************/ +/* Clock Output Configuration register definition */ +/** Selects the CPU clock as the CLKOUT source */ +#define CLKPWR_CLKOUTCFG_CLKOUTSEL_CPU ((uint32_t)(0x00)) +/** Selects the main oscillator as the CLKOUT source */ +#define CLKPWR_CLKOUTCFG_CLKOUTSEL_MAINOSC ((uint32_t)(0x01)) +/** Selects the Internal RC oscillator as the CLKOUT source */ +#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RC ((uint32_t)(0x02)) +/** Selects the USB clock as the CLKOUT source */ +#define CLKPWR_CLKOUTCFG_CLKOUTSEL_USB ((uint32_t)(0x03)) +/** Selects the RTC oscillator as the CLKOUT source */ +#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RTC ((uint32_t)(0x04)) +/** Integer value to divide the output clock by, minus one */ +#define CLKPWR_CLKOUTCFG_CLKOUTDIV(n) ((uint32_t)((n&0x0F)<<4)) +/** CLKOUT enable control */ +#define CLKPWR_CLKOUTCFG_CLKOUT_EN ((uint32_t)(1<<8)) +/** CLKOUT activity indication */ +#define CLKPWR_CLKOUTCFG_CLKOUT_ACT ((uint32_t)(1<<9)) +/** Clock source selection bit mask */ +#define CLKPWR_CLKOUTCFG_BITMASK ((uint32_t)(0x3FF)) + +/*********************************************************************//** + * Macro defines for PPL0 Control Register + **********************************************************************/ +/** PLL 0 control enable */ +#define CLKPWR_PLL0CON_ENABLE ((uint32_t)(0x01)) +/** PLL 0 control connect */ +#define CLKPWR_PLL0CON_CONNECT ((uint32_t)(0x02)) +/** PLL 0 control bit mask */ +#define CLKPWR_PLL0CON_BITMASK ((uint32_t)(0x03)) + +/*********************************************************************//** + * Macro defines for PPL0 Configuration Register + **********************************************************************/ +/** PLL 0 Configuration MSEL field */ +#define CLKPWR_PLL0CFG_MSEL(n) ((uint32_t)(n&0x7FFF)) +/** PLL 0 Configuration NSEL field */ +#define CLKPWR_PLL0CFG_NSEL(n) ((uint32_t)((n<<16)&0xFF0000)) +/** PLL 0 Configuration bit mask */ +#define CLKPWR_PLL0CFG_BITMASK ((uint32_t)(0xFF7FFF)) + + +/*********************************************************************//** + * Macro defines for PPL0 Status Register + **********************************************************************/ +/** PLL 0 MSEL value */ +#define CLKPWR_PLL0STAT_MSEL(n) ((uint32_t)(n&0x7FFF)) +/** PLL NSEL get value */ +#define CLKPWR_PLL0STAT_NSEL(n) ((uint32_t)((n>>16)&0xFF)) +/** PLL status enable bit */ +#define CLKPWR_PLL0STAT_PLLE ((uint32_t)(1<<24)) +/** PLL status Connect bit */ +#define CLKPWR_PLL0STAT_PLLC ((uint32_t)(1<<25)) +/** PLL status lock */ +#define CLKPWR_PLL0STAT_PLOCK ((uint32_t)(1<<26)) + +/*********************************************************************//** + * Macro defines for PPL0 Feed Register + **********************************************************************/ +/** PLL0 Feed bit mask */ +#define CLKPWR_PLL0FEED_BITMASK ((uint32_t)0xFF) + +/*********************************************************************//** + * Macro defines for PLL1 Control Register + **********************************************************************/ +/** USB PLL control enable */ +#define CLKPWR_PLL1CON_ENABLE ((uint32_t)(0x01)) +/** USB PLL control connect */ +#define CLKPWR_PLL1CON_CONNECT ((uint32_t)(0x02)) +/** USB PLL control bit mask */ +#define CLKPWR_PLL1CON_BITMASK ((uint32_t)(0x03)) + +/*********************************************************************//** + * Macro defines for PLL1 Configuration Register + **********************************************************************/ +/** USB PLL MSEL set value */ +#define CLKPWR_PLL1CFG_MSEL(n) ((uint32_t)(n&0x1F)) +/** USB PLL PSEL set value */ +#define CLKPWR_PLL1CFG_PSEL(n) ((uint32_t)((n&0x03)<<5)) +/** USB PLL configuration bit mask */ +#define CLKPWR_PLL1CFG_BITMASK ((uint32_t)(0x7F)) + +/*********************************************************************//** + * Macro defines for PLL1 Status Register + **********************************************************************/ +/** USB PLL MSEL get value */ +#define CLKPWR_PLL1STAT_MSEL(n) ((uint32_t)(n&0x1F)) +/** USB PLL PSEL get value */ +#define CLKPWR_PLL1STAT_PSEL(n) ((uint32_t)((n>>5)&0x03)) +/** USB PLL status enable bit */ +#define CLKPWR_PLL1STAT_PLLE ((uint32_t)(1<<8)) +/** USB PLL status Connect bit */ +#define CLKPWR_PLL1STAT_PLLC ((uint32_t)(1<<9)) +/** USB PLL status lock */ +#define CLKPWR_PLL1STAT_PLOCK ((uint32_t)(1<<10)) + +/*********************************************************************//** + * Macro defines for PLL1 Feed Register + **********************************************************************/ +/** PLL1 Feed bit mask */ +#define CLKPWR_PLL1FEED_BITMASK ((uint32_t)0xFF) + +/*********************************************************************//** + * Macro defines for CPU Clock Configuration Register + **********************************************************************/ +/** CPU Clock configuration bit mask */ +#define CLKPWR_CCLKCFG_BITMASK ((uint32_t)(0xFF)) + +/*********************************************************************//** + * Macro defines for USB Clock Configuration Register + **********************************************************************/ +/** USB Clock Configuration bit mask */ +#define CLKPWR_USBCLKCFG_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro defines for IRC Trim Register + **********************************************************************/ +/** IRC Trim bit mask */ +#define CLKPWR_IRCTRIM_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro defines for Peripheral Clock Selection Register 0 and 1 + **********************************************************************/ +/** Peripheral Clock Selection 0 mask bit */ +#define CLKPWR_PCLKSEL0_BITMASK ((uint32_t)(0xFFF3F3FF)) +/** Peripheral Clock Selection 1 mask bit */ +#define CLKPWR_PCLKSEL1_BITMASK ((uint32_t)(0xFCF3F0F3)) +/** Macro to set peripheral clock of each type + * p: position of two bits that hold divider of peripheral clock + * n: value of divider of peripheral clock to be set */ +#define CLKPWR_PCLKSEL_SET(p,n) _SBF(p,n) +/** Macro to mask peripheral clock of each type */ +#define CLKPWR_PCLKSEL_BITMASK(p) _SBF(p,0x03) +/** Macro to get peripheral clock of each type */ +#define CLKPWR_PCLKSEL_GET(p, n) ((uint32_t)((n>>p)&0x03)) + +/*********************************************************************//** + * Macro defines for Power Mode Control Register + **********************************************************************/ +/** Power mode control bit 0 */ +#define CLKPWR_PCON_PM0 ((uint32_t)(1<<0)) +/** Power mode control bit 1 */ +#define CLKPWR_PCON_PM1 ((uint32_t)(1<<1)) +/** Brown-Out Reduced Power Mode */ +#define CLKPWR_PCON_BODPDM ((uint32_t)(1<<2)) +/** Brown-Out Global Disable */ +#define CLKPWR_PCON_BOGD ((uint32_t)(1<<3)) +/** Brown Out Reset Disable */ +#define CLKPWR_PCON_BORD ((uint32_t)(1<<4)) +/** Sleep Mode entry flag */ +#define CLKPWR_PCON_SMFLAG ((uint32_t)(1<<8)) +/** Deep Sleep entry flag */ +#define CLKPWR_PCON_DSFLAG ((uint32_t)(1<<9)) +/** Power-down entry flag */ +#define CLKPWR_PCON_PDFLAG ((uint32_t)(1<<10)) +/** Deep Power-down entry flag */ +#define CLKPWR_PCON_DPDFLAG ((uint32_t)(1<<11)) + +/*********************************************************************//** + * Macro defines for Power Control for Peripheral Register + **********************************************************************/ +/** Power Control for Peripherals bit mask */ +#define CLKPWR_PCONP_BITMASK 0xEFEFF7DE + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup CLKPWR_Public_Functions CLKPWR Public Functions + * @{ + */ + +void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal); +uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType); +uint32_t CLKPWR_GetPCLK (uint32_t ClkType); +void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState); +void CLKPWR_Sleep(void); +void CLKPWR_DeepSleep(void); +void CLKPWR_PowerDown(void); +void CLKPWR_DeepPowerDown(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_CLKPWR_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_dac.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_dac.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,139 @@ +/** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_dac.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_dac.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,142 @@ +/***********************************************************************//** + * @file lpc17xx_dac.h + * @brief Contains all macro definitions and function prototypes + * support for DAC firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup DAC DAC + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_DAC_H_ +#define LPC17XX_DAC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup DAC_Private_Macros DAC Private Macros + * @{ + */ + +/** After the selected settling time after this field is written with a +new VALUE, the voltage on the AOUT pin (with respect to VSSA) +is VALUE/1024 × VREF */ +#define DAC_VALUE(n) ((uint32_t)((n&0x3FF)<<6)) +/** If this bit = 0: The settling time of the DAC is 1 microsecond max, + * and the maximum current is 700 microAmpere + * If this bit = 1: The settling time of the DAC is 2.5 microsecond + * and the maximum current is 350 microAmpere */ +#define DAC_BIAS_EN ((uint32_t)(1<<16)) +/** Value to reload interrupt DMA counter */ +#define DAC_CCNT_VALUE(n) ((uint32_t)(n&0xffff)) + +/** DCAR double buffering */ +#define DAC_DBLBUF_ENA ((uint32_t)(1<<1)) +/** DCAR Time out count enable */ +#define DAC_CNT_ENA ((uint32_t)(1<<2)) +/** DCAR DMA access */ +#define DAC_DMA_ENA ((uint32_t)(1<<3)) +/** DCAR DACCTRL mask bit */ +#define DAC_DACCTRL_MASK ((uint32_t)(0x0F)) + +/** Macro to determine if it is valid DAC peripheral */ +#define PARAM_DACx(n) (((uint32_t *)n)==((uint32_t *)LPC_DAC)) + +/** Macro to check DAC current optional parameter */ +#define PARAM_DAC_CURRENT_OPT(OPTION) ((OPTION == DAC_MAX_CURRENT_700uA)\ +||(OPTION == DAC_MAX_CURRENT_350uA)) +/** + * @} + */ +/* Public Types --------------------------------------------------------------- */ +/** @defgroup DAC_Public_Types DAC Public Types + * @{ + */ + +/** + * @brief Current option in DAC configuration option */ +typedef enum +{ + DAC_MAX_CURRENT_700uA = 0, /*!< The settling time of the DAC is 1 us max, + and the maximum current is 700 uA */ + DAC_MAX_CURRENT_350uA /*!< The settling time of the DAC is 2.5 us + and the maximum current is 350 uA */ +} DAC_CURRENT_OPT; + +/** + * @brief Configuration for DAC converter control register */ +typedef struct +{ + + uint8_t DBLBUF_ENA; /**< + -0: Disable DACR double buffering + -1: when bit CNT_ENA, enable DACR double buffering feature + */ + uint8_t CNT_ENA; /*!< + -0: Time out counter is disable + -1: Time out conter is enable + */ + uint8_t DMA_ENA; /*!< + -0: DMA access is disable + -1: DMA burst request + */ + uint8_t RESERVED; + +} DAC_CONVERTER_CFG_Type; + +/** + * @} + */ + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup DAC_Public_Functions DAC Public Functions + * @{ + */ + +void DAC_Init(LPC_DAC_TypeDef *DACx); +void DAC_UpdateValue (LPC_DAC_TypeDef *DACx, uint32_t dac_value); +void DAC_SetBias (LPC_DAC_TypeDef *DACx,uint32_t bias); +void DAC_ConfigDAConverterControl (LPC_DAC_TypeDef *DACx,DAC_CONVERTER_CFG_Type *DAC_ConverterConfigStruct); +void DAC_SetDMATimeOut(LPC_DAC_TypeDef *DACx,uint32_t time_out); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC17XX_DAC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_emac.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_emac.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,950 @@ +/** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 }; + +/* 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; 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, regv; + + /* 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; tout--) { + regv = read_PHY (EMAC_PHY_REG_BMSR); + if (regv & EMAC_PHY_BMSR_AUTO_DONE) { + /* Auto-negotiation Complete. */ + break; + } + if (tout == 0){ + // Time out, return error + return (-1); + } + } + 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; 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; 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 -1; + if (LPC_EMAC->TxProduceIndex == tmp) { + 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_emac.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_emac.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,699 @@ +/***********************************************************************//** + * @file lpc17xx_emac.h + * @brief Contains all macro definitions and function prototypes + * support for Ethernet MAC firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup EMAC EMAC + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_EMAC_H_ +#define LPC17XX_EMAC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MCB_LPC_1768 +//#define IAR_LPC_1768 + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup EMAC_Public_Macros EMAC Public Macros + * @{ + */ + + +/* EMAC PHY status type definitions */ +#define EMAC_PHY_STAT_LINK (0) /**< Link Status */ +#define EMAC_PHY_STAT_SPEED (1) /**< Speed Status */ +#define EMAC_PHY_STAT_DUP (2) /**< Duplex Status */ + +/* EMAC PHY device Speed definitions */ +#define EMAC_MODE_AUTO (0) /**< Auto-negotiation mode */ +#define EMAC_MODE_10M_FULL (1) /**< 10Mbps FullDuplex mode */ +#define EMAC_MODE_10M_HALF (2) /**< 10Mbps HalfDuplex mode */ +#define EMAC_MODE_100M_FULL (3) /**< 100Mbps FullDuplex mode */ +#define EMAC_MODE_100M_HALF (4) /**< 100Mbps HalfDuplex mode */ + +/** + * @} + */ +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup EMAC_Private_Macros EMAC Private Macros + * @{ + */ + + +/* EMAC Memory Buffer configuration for 16K Ethernet RAM */ +#define EMAC_NUM_RX_FRAG 4 /**< Num.of RX Fragments 4*1536= 6.0kB */ +#define EMAC_NUM_TX_FRAG 3 /**< Num.of TX Fragments 3*1536= 4.6kB */ +#define EMAC_ETH_MAX_FLEN 1536 /**< Max. Ethernet Frame Size */ +#define EMAC_TX_FRAME_TOUT 0x00100000 /**< Frame Transmit timeout count */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for MAC Configuration Register 1 + **********************************************************************/ +#define EMAC_MAC1_REC_EN 0x00000001 /**< Receive Enable */ +#define EMAC_MAC1_PASS_ALL 0x00000002 /**< Pass All Receive Frames */ +#define EMAC_MAC1_RX_FLOWC 0x00000004 /**< RX Flow Control */ +#define EMAC_MAC1_TX_FLOWC 0x00000008 /**< TX Flow Control */ +#define EMAC_MAC1_LOOPB 0x00000010 /**< Loop Back Mode */ +#define EMAC_MAC1_RES_TX 0x00000100 /**< Reset TX Logic */ +#define EMAC_MAC1_RES_MCS_TX 0x00000200 /**< Reset MAC TX Control Sublayer */ +#define EMAC_MAC1_RES_RX 0x00000400 /**< Reset RX Logic */ +#define EMAC_MAC1_RES_MCS_RX 0x00000800 /**< Reset MAC RX Control Sublayer */ +#define EMAC_MAC1_SIM_RES 0x00004000 /**< Simulation Reset */ +#define EMAC_MAC1_SOFT_RES 0x00008000 /**< Soft Reset MAC */ + +/*********************************************************************//** + * Macro defines for MAC Configuration Register 2 + **********************************************************************/ +#define EMAC_MAC2_FULL_DUP 0x00000001 /**< Full-Duplex Mode */ +#define EMAC_MAC2_FRM_LEN_CHK 0x00000002 /**< Frame Length Checking */ +#define EMAC_MAC2_HUGE_FRM_EN 0x00000004 /**< Huge Frame Enable */ +#define EMAC_MAC2_DLY_CRC 0x00000008 /**< Delayed CRC Mode */ +#define EMAC_MAC2_CRC_EN 0x00000010 /**< Append CRC to every Frame */ +#define EMAC_MAC2_PAD_EN 0x00000020 /**< Pad all Short Frames */ +#define EMAC_MAC2_VLAN_PAD_EN 0x00000040 /**< VLAN Pad Enable */ +#define EMAC_MAC2_ADET_PAD_EN 0x00000080 /**< Auto Detect Pad Enable */ +#define EMAC_MAC2_PPREAM_ENF 0x00000100 /**< Pure Preamble Enforcement */ +#define EMAC_MAC2_LPREAM_ENF 0x00000200 /**< Long Preamble Enforcement */ +#define EMAC_MAC2_NO_BACKOFF 0x00001000 /**< No Backoff Algorithm */ +#define EMAC_MAC2_BACK_PRESSURE 0x00002000 /**< Backoff Presurre / No Backoff */ +#define EMAC_MAC2_EXCESS_DEF 0x00004000 /**< Excess Defer */ + +/*********************************************************************//** + * Macro defines for Back-to-Back Inter-Packet-Gap Register + **********************************************************************/ +/** Programmable field representing the nibble time offset of the minimum possible period + * between the end of any transmitted packet to the beginning of the next */ +#define EMAC_IPGT_BBIPG(n) (n&0x7F) +/** Recommended value for Full Duplex of Programmable field representing the nibble time + * offset of the minimum possible period between the end of any transmitted packet to the + * beginning of the next */ +#define EMAC_IPGT_FULL_DUP (EMAC_IPGT_BBIPG(0x15)) +/** Recommended value for Half Duplex of Programmable field representing the nibble time + * offset of the minimum possible period between the end of any transmitted packet to the + * beginning of the next */ +#define EMAC_IPGT_HALF_DUP (EMAC_IPGT_BBIPG(0x12)) + +/*********************************************************************//** + * Macro defines for Non Back-to-Back Inter-Packet-Gap Register + **********************************************************************/ +/** Programmable field representing the Non-Back-to-Back Inter-Packet-Gap */ +#define EMAC_IPGR_NBBIPG_P2(n) (n&0x7F) +/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 1 */ +#define EMAC_IPGR_P2_DEF (EMAC_IPGR_NBBIPG_P2(0x12)) +/** Programmable field representing the optional carrierSense window referenced in + * IEEE 802.3/4.2.3.2.1 'Carrier Deference' */ +#define EMAC_IPGR_NBBIPG_P1(n) ((n&0x7F)<<8) +/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 2 */ +#define EMAC_IPGR_P1_DEF EMAC_IPGR_NBBIPG_P1(0x0C) + +/*********************************************************************//** + * Macro defines for Collision Window/Retry Register + **********************************************************************/ +/** Programmable field specifying the number of retransmission attempts following a collision before + * aborting the packet due to excessive collisions */ +#define EMAC_CLRT_MAX_RETX(n) (n&0x0F) +/** Programmable field representing the slot time or collision window during which collisions occur + * in properly configured networks */ +#define EMAC_CLRT_COLL(n) ((n&0x3F)<<8) +/** Default value for Collision Window / Retry register */ +#define EMAC_CLRT_DEF ((EMAC_CLRT_MAX_RETX(0x0F))|(EMAC_CLRT_COLL(0x37))) + +/*********************************************************************//** + * Macro defines for Maximum Frame Register + **********************************************************************/ +/** Represents a maximum receive frame of 1536 octets */ +#define EMAC_MAXF_MAXFRMLEN(n) (n&0xFFFF) + +/*********************************************************************//** + * Macro defines for PHY Support Register + **********************************************************************/ +#define EMAC_SUPP_SPEED 0x00000100 /**< Reduced MII Logic Current Speed */ +#define EMAC_SUPP_RES_RMII 0x00000800 /**< Reset Reduced MII Logic */ + +/*********************************************************************//** + * Macro defines for Test Register + **********************************************************************/ +#define EMAC_TEST_SHCUT_PQUANTA 0x00000001 /**< Shortcut Pause Quanta */ +#define EMAC_TEST_TST_PAUSE 0x00000002 /**< Test Pause */ +#define EMAC_TEST_TST_BACKP 0x00000004 /**< Test Back Pressure */ + +/*********************************************************************//** + * Macro defines for MII Management Configuration Register + **********************************************************************/ +#define EMAC_MCFG_SCAN_INC 0x00000001 /**< Scan Increment PHY Address */ +#define EMAC_MCFG_SUPP_PREAM 0x00000002 /**< Suppress Preamble */ +#define EMAC_MCFG_CLK_SEL(n) ((n&0x0F)<<2) /**< Clock Select Field */ +#define EMAC_MCFG_RES_MII 0x00008000 /**< Reset MII Management Hardware */ +#define EMAC_MCFG_MII_MAXCLK 2500000UL /**< MII Clock max */ + +/*********************************************************************//** + * Macro defines for MII Management Command Register + **********************************************************************/ +#define EMAC_MCMD_READ 0x00000001 /**< MII Read */ +#define EMAC_MCMD_SCAN 0x00000002 /**< MII Scan continuously */ + +#define EMAC_MII_WR_TOUT 0x00050000 /**< MII Write timeout count */ +#define EMAC_MII_RD_TOUT 0x00050000 /**< MII Read timeout count */ + +/*********************************************************************//** + * Macro defines for MII Management Address Register + **********************************************************************/ +#define EMAC_MADR_REG_ADR(n) (n&0x1F) /**< MII Register Address field */ +#define EMAC_MADR_PHY_ADR(n) ((n&0x1F)<<8) /**< PHY Address Field */ + +/*********************************************************************//** + * Macro defines for MII Management Write Data Register + **********************************************************************/ +#define EMAC_MWTD_DATA(n) (n&0xFFFF) /**< Data field for MMI Management Write Data register */ + +/*********************************************************************//** + * Macro defines for MII Management Read Data Register + **********************************************************************/ +#define EMAC_MRDD_DATA(n) (n&0xFFFF) /**< Data field for MMI Management Read Data register */ + +/*********************************************************************//** + * Macro defines for MII Management Indicators Register + **********************************************************************/ +#define EMAC_MIND_BUSY 0x00000001 /**< MII is Busy */ +#define EMAC_MIND_SCAN 0x00000002 /**< MII Scanning in Progress */ +#define EMAC_MIND_NOT_VAL 0x00000004 /**< MII Read Data not valid */ +#define EMAC_MIND_MII_LINK_FAIL 0x00000008 /**< MII Link Failed */ + +/* Station Address 0 Register */ +/* Station Address 1 Register */ +/* Station Address 2 Register */ + + +/* Control register definitions --------------------------------------------------------------------------- */ +/*********************************************************************//** + * Macro defines for Command Register + **********************************************************************/ +#define EMAC_CR_RX_EN 0x00000001 /**< Enable Receive */ +#define EMAC_CR_TX_EN 0x00000002 /**< Enable Transmit */ +#define EMAC_CR_REG_RES 0x00000008 /**< Reset Host Registers */ +#define EMAC_CR_TX_RES 0x00000010 /**< Reset Transmit Datapath */ +#define EMAC_CR_RX_RES 0x00000020 /**< Reset Receive Datapath */ +#define EMAC_CR_PASS_RUNT_FRM 0x00000040 /**< Pass Runt Frames */ +#define EMAC_CR_PASS_RX_FILT 0x00000080 /**< Pass RX Filter */ +#define EMAC_CR_TX_FLOW_CTRL 0x00000100 /**< TX Flow Control */ +#define EMAC_CR_RMII 0x00000200 /**< Reduced MII Interface */ +#define EMAC_CR_FULL_DUP 0x00000400 /**< Full Duplex */ + +/*********************************************************************//** + * Macro defines for Status Register + **********************************************************************/ +#define EMAC_SR_RX_EN 0x00000001 /**< Enable Receive */ +#define EMAC_SR_TX_EN 0x00000002 /**< Enable Transmit */ + +/*********************************************************************//** + * Macro defines for Transmit Status Vector 0 Register + **********************************************************************/ +#define EMAC_TSV0_CRC_ERR 0x00000001 /**< CRC error */ +#define EMAC_TSV0_LEN_CHKERR 0x00000002 /**< Length Check Error */ +#define EMAC_TSV0_LEN_OUTRNG 0x00000004 /**< Length Out of Range */ +#define EMAC_TSV0_DONE 0x00000008 /**< Tramsmission Completed */ +#define EMAC_TSV0_MCAST 0x00000010 /**< Multicast Destination */ +#define EMAC_TSV0_BCAST 0x00000020 /**< Broadcast Destination */ +#define EMAC_TSV0_PKT_DEFER 0x00000040 /**< Packet Deferred */ +#define EMAC_TSV0_EXC_DEFER 0x00000080 /**< Excessive Packet Deferral */ +#define EMAC_TSV0_EXC_COLL 0x00000100 /**< Excessive Collision */ +#define EMAC_TSV0_LATE_COLL 0x00000200 /**< Late Collision Occured */ +#define EMAC_TSV0_GIANT 0x00000400 /**< Giant Frame */ +#define EMAC_TSV0_UNDERRUN 0x00000800 /**< Buffer Underrun */ +#define EMAC_TSV0_BYTES 0x0FFFF000 /**< Total Bytes Transferred */ +#define EMAC_TSV0_CTRL_FRAME 0x10000000 /**< Control Frame */ +#define EMAC_TSV0_PAUSE 0x20000000 /**< Pause Frame */ +#define EMAC_TSV0_BACK_PRESS 0x40000000 /**< Backpressure Method Applied */ +#define EMAC_TSV0_VLAN 0x80000000 /**< VLAN Frame */ + +/*********************************************************************//** + * Macro defines for Transmit Status Vector 1 Register + **********************************************************************/ +#define EMAC_TSV1_BYTE_CNT 0x0000FFFF /**< Transmit Byte Count */ +#define EMAC_TSV1_COLL_CNT 0x000F0000 /**< Transmit Collision Count */ + +/*********************************************************************//** + * Macro defines for Receive Status Vector Register + **********************************************************************/ +#define EMAC_RSV_BYTE_CNT 0x0000FFFF /**< Receive Byte Count */ +#define EMAC_RSV_PKT_IGNORED 0x00010000 /**< Packet Previously Ignored */ +#define EMAC_RSV_RXDV_SEEN 0x00020000 /**< RXDV Event Previously Seen */ +#define EMAC_RSV_CARR_SEEN 0x00040000 /**< Carrier Event Previously Seen */ +#define EMAC_RSV_REC_CODEV 0x00080000 /**< Receive Code Violation */ +#define EMAC_RSV_CRC_ERR 0x00100000 /**< CRC Error */ +#define EMAC_RSV_LEN_CHKERR 0x00200000 /**< Length Check Error */ +#define EMAC_RSV_LEN_OUTRNG 0x00400000 /**< Length Out of Range */ +#define EMAC_RSV_REC_OK 0x00800000 /**< Frame Received OK */ +#define EMAC_RSV_MCAST 0x01000000 /**< Multicast Frame */ +#define EMAC_RSV_BCAST 0x02000000 /**< Broadcast Frame */ +#define EMAC_RSV_DRIB_NIBB 0x04000000 /**< Dribble Nibble */ +#define EMAC_RSV_CTRL_FRAME 0x08000000 /**< Control Frame */ +#define EMAC_RSV_PAUSE 0x10000000 /**< Pause Frame */ +#define EMAC_RSV_UNSUPP_OPC 0x20000000 /**< Unsupported Opcode */ +#define EMAC_RSV_VLAN 0x40000000 /**< VLAN Frame */ + +/*********************************************************************//** + * Macro defines for Flow Control Counter Register + **********************************************************************/ +#define EMAC_FCC_MIRR_CNT(n) (n&0xFFFF) /**< Mirror Counter */ +#define EMAC_FCC_PAUSE_TIM(n) ((n&0xFFFF)<<16) /**< Pause Timer */ + +/*********************************************************************//** + * Macro defines for Flow Control Status Register + **********************************************************************/ +#define EMAC_FCS_MIRR_CNT(n) (n&0xFFFF) /**< Mirror Counter Current */ + + +/* Receive filter register definitions -------------------------------------------------------- */ +/*********************************************************************//** + * Macro defines for Receive Filter Control Register + **********************************************************************/ +#define EMAC_RFC_UCAST_EN 0x00000001 /**< Accept Unicast Frames Enable */ +#define EMAC_RFC_BCAST_EN 0x00000002 /**< Accept Broadcast Frames Enable */ +#define EMAC_RFC_MCAST_EN 0x00000004 /**< Accept Multicast Frames Enable */ +#define EMAC_RFC_UCAST_HASH_EN 0x00000008 /**< Accept Unicast Hash Filter Frames */ +#define EMAC_RFC_MCAST_HASH_EN 0x00000010 /**< Accept Multicast Hash Filter Fram.*/ +#define EMAC_RFC_PERFECT_EN 0x00000020 /**< Accept Perfect Match Enable */ +#define EMAC_RFC_MAGP_WOL_EN 0x00001000 /**< Magic Packet Filter WoL Enable */ +#define EMAC_RFC_PFILT_WOL_EN 0x00002000 /**< Perfect Filter WoL Enable */ + +/*********************************************************************//** + * Macro defines for Receive Filter WoL Status/Clear Registers + **********************************************************************/ +#define EMAC_WOL_UCAST 0x00000001 /**< Unicast Frame caused WoL */ +#define EMAC_WOL_BCAST 0x00000002 /**< Broadcast Frame caused WoL */ +#define EMAC_WOL_MCAST 0x00000004 /**< Multicast Frame caused WoL */ +#define EMAC_WOL_UCAST_HASH 0x00000008 /**< Unicast Hash Filter Frame WoL */ +#define EMAC_WOL_MCAST_HASH 0x00000010 /**< Multicast Hash Filter Frame WoL */ +#define EMAC_WOL_PERFECT 0x00000020 /**< Perfect Filter WoL */ +#define EMAC_WOL_RX_FILTER 0x00000080 /**< RX Filter caused WoL */ +#define EMAC_WOL_MAG_PACKET 0x00000100 /**< Magic Packet Filter caused WoL */ +#define EMAC_WOL_BITMASK 0x01BF /**< Receive Filter WoL Status/Clear bitmasl value */ + + +/* Module control register definitions ---------------------------------------------------- */ +/*********************************************************************//** + * Macro defines for Interrupt Status/Enable/Clear/Set Registers + **********************************************************************/ +#define EMAC_INT_RX_OVERRUN 0x00000001 /**< Overrun Error in RX Queue */ +#define EMAC_INT_RX_ERR 0x00000002 /**< Receive Error */ +#define EMAC_INT_RX_FIN 0x00000004 /**< RX Finished Process Descriptors */ +#define EMAC_INT_RX_DONE 0x00000008 /**< Receive Done */ +#define EMAC_INT_TX_UNDERRUN 0x00000010 /**< Transmit Underrun */ +#define EMAC_INT_TX_ERR 0x00000020 /**< Transmit Error */ +#define EMAC_INT_TX_FIN 0x00000040 /**< TX Finished Process Descriptors */ +#define EMAC_INT_TX_DONE 0x00000080 /**< Transmit Done */ +#define EMAC_INT_SOFT_INT 0x00001000 /**< Software Triggered Interrupt */ +#define EMAC_INT_WAKEUP 0x00002000 /**< Wakeup Event Interrupt */ + +/*********************************************************************//** + * Macro defines for Power Down Register + **********************************************************************/ +#define EMAC_PD_POWER_DOWN 0x80000000 /**< Power Down MAC */ + +/* Descriptor and status formats ---------------------------------------------------- */ +/*********************************************************************//** + * Macro defines for RX Descriptor Control Word + **********************************************************************/ +#define EMAC_RCTRL_SIZE(n) (n&0x7FF) /**< Buffer size field */ +#define EMAC_RCTRL_INT 0x80000000 /**< Generate RxDone Interrupt */ + +/*********************************************************************//** + * Macro defines for RX Status Hash CRC Word + **********************************************************************/ +#define EMAC_RHASH_SA 0x000001FF /**< Hash CRC for Source Address */ +#define EMAC_RHASH_DA 0x001FF000 /**< Hash CRC for Destination Address */ + +/*********************************************************************//** + * Macro defines for RX Status Information Word + **********************************************************************/ +#define EMAC_RINFO_SIZE 0x000007FF /**< Data size in bytes */ +#define EMAC_RINFO_CTRL_FRAME 0x00040000 /**< Control Frame */ +#define EMAC_RINFO_VLAN 0x00080000 /**< VLAN Frame */ +#define EMAC_RINFO_FAIL_FILT 0x00100000 /**< RX Filter Failed */ +#define EMAC_RINFO_MCAST 0x00200000 /**< Multicast Frame */ +#define EMAC_RINFO_BCAST 0x00400000 /**< Broadcast Frame */ +#define EMAC_RINFO_CRC_ERR 0x00800000 /**< CRC Error in Frame */ +#define EMAC_RINFO_SYM_ERR 0x01000000 /**< Symbol Error from PHY */ +#define EMAC_RINFO_LEN_ERR 0x02000000 /**< Length Error */ +#define EMAC_RINFO_RANGE_ERR 0x04000000 /**< Range Error (exceeded max. size) */ +#define EMAC_RINFO_ALIGN_ERR 0x08000000 /**< Alignment Error */ +#define EMAC_RINFO_OVERRUN 0x10000000 /**< Receive overrun */ +#define EMAC_RINFO_NO_DESCR 0x20000000 /**< No new Descriptor available */ +#define EMAC_RINFO_LAST_FLAG 0x40000000 /**< Last Fragment in Frame */ +#define EMAC_RINFO_ERR 0x80000000 /**< Error Occured (OR of all errors) */ +#define EMAC_RINFO_ERR_MASK (EMAC_RINFO_FAIL_FILT | EMAC_RINFO_CRC_ERR | EMAC_RINFO_SYM_ERR | \ +EMAC_RINFO_LEN_ERR | EMAC_RINFO_ALIGN_ERR | EMAC_RINFO_OVERRUN) + +/*********************************************************************//** + * Macro defines for TX Descriptor Control Word + **********************************************************************/ +#define EMAC_TCTRL_SIZE 0x000007FF /**< Size of data buffer in bytes */ +#define EMAC_TCTRL_OVERRIDE 0x04000000 /**< Override Default MAC Registers */ +#define EMAC_TCTRL_HUGE 0x08000000 /**< Enable Huge Frame */ +#define EMAC_TCTRL_PAD 0x10000000 /**< Pad short Frames to 64 bytes */ +#define EMAC_TCTRL_CRC 0x20000000 /**< Append a hardware CRC to Frame */ +#define EMAC_TCTRL_LAST 0x40000000 /**< Last Descriptor for TX Frame */ +#define EMAC_TCTRL_INT 0x80000000 /**< Generate TxDone Interrupt */ + +/*********************************************************************//** + * Macro defines for TX Status Information Word + **********************************************************************/ +#define EMAC_TINFO_COL_CNT 0x01E00000 /**< Collision Count */ +#define EMAC_TINFO_DEFER 0x02000000 /**< Packet Deferred (not an error) */ +#define EMAC_TINFO_EXCESS_DEF 0x04000000 /**< Excessive Deferral */ +#define EMAC_TINFO_EXCESS_COL 0x08000000 /**< Excessive Collision */ +#define EMAC_TINFO_LATE_COL 0x10000000 /**< Late Collision Occured */ +#define EMAC_TINFO_UNDERRUN 0x20000000 /**< Transmit Underrun */ +#define EMAC_TINFO_NO_DESCR 0x40000000 /**< No new Descriptor available */ +#define EMAC_TINFO_ERR 0x80000000 /**< Error Occured (OR of all errors) */ + +#ifdef MCB_LPC_1768 +/* DP83848C PHY definition ------------------------------------------------------------ */ + +/** PHY device reset time out definition */ +#define EMAC_PHY_RESP_TOUT 0x100000UL + +/* ENET Device Revision ID */ +#define EMAC_OLD_EMAC_MODULE_ID 0x39022000 /**< Rev. ID for first rev '-' */ + +/*********************************************************************//** + * Macro defines for DP83848C PHY Registers + **********************************************************************/ +#define EMAC_PHY_REG_BMCR 0x00 /**< Basic Mode Control Register */ +#define EMAC_PHY_REG_BMSR 0x01 /**< Basic Mode Status Register */ +#define EMAC_PHY_REG_IDR1 0x02 /**< PHY Identifier 1 */ +#define EMAC_PHY_REG_IDR2 0x03 /**< PHY Identifier 2 */ +#define EMAC_PHY_REG_ANAR 0x04 /**< Auto-Negotiation Advertisement */ +#define EMAC_PHY_REG_ANLPAR 0x05 /**< Auto-Neg. Link Partner Abitily */ +#define EMAC_PHY_REG_ANER 0x06 /**< Auto-Neg. Expansion Register */ +#define EMAC_PHY_REG_ANNPTR 0x07 /**< Auto-Neg. Next Page TX */ +#define EMAC_PHY_REG_LPNPA 0x08 + +/*********************************************************************//** + * Macro defines for PHY Extended Registers + **********************************************************************/ +#define EMAC_PHY_REG_STS 0x10 /**< Status Register */ +#define EMAC_PHY_REG_MICR 0x11 /**< MII Interrupt Control Register */ +#define EMAC_PHY_REG_MISR 0x12 /**< MII Interrupt Status Register */ +#define EMAC_PHY_REG_FCSCR 0x14 /**< False Carrier Sense Counter */ +#define EMAC_PHY_REG_RECR 0x15 /**< Receive Error Counter */ +#define EMAC_PHY_REG_PCSR 0x16 /**< PCS Sublayer Config. and Status */ +#define EMAC_PHY_REG_RBR 0x17 /**< RMII and Bypass Register */ +#define EMAC_PHY_REG_LEDCR 0x18 /**< LED Direct Control Register */ +#define EMAC_PHY_REG_PHYCR 0x19 /**< PHY Control Register */ +#define EMAC_PHY_REG_10BTSCR 0x1A /**< 10Base-T Status/Control Register */ +#define EMAC_PHY_REG_CDCTRL1 0x1B /**< CD Test Control and BIST Extens. */ +#define EMAC_PHY_REG_EDCR 0x1D /**< Energy Detect Control Register */ + +/*********************************************************************//** + * Macro defines for PHY Basic Mode Control Register + **********************************************************************/ +#define EMAC_PHY_BMCR_RESET (1<<15) /**< Reset bit */ +#define EMAC_PHY_BMCR_LOOPBACK (1<<14) /**< Loop back */ +#define EMAC_PHY_BMCR_SPEED_SEL (1<<13) /**< Speed selection */ +#define EMAC_PHY_BMCR_AN (1<<12) /**< Auto Negotiation */ +#define EMAC_PHY_BMCR_POWERDOWN (1<<11) /**< Power down mode */ +#define EMAC_PHY_BMCR_ISOLATE (1<<10) /**< Isolate */ +#define EMAC_PHY_BMCR_RE_AN (1<<9) /**< Restart auto negotiation */ +#define EMAC_PHY_BMCR_DUPLEX (1<<8) /**< Duplex mode */ + +/*********************************************************************//** + * Macro defines for PHY Basic Mode Status Status Register + **********************************************************************/ +#define EMAC_PHY_BMSR_100BE_T4 (1<<15) /**< 100 base T4 */ +#define EMAC_PHY_BMSR_100TX_FULL (1<<14) /**< 100 base full duplex */ +#define EMAC_PHY_BMSR_100TX_HALF (1<<13) /**< 100 base half duplex */ +#define EMAC_PHY_BMSR_10BE_FULL (1<<12) /**< 10 base T full duplex */ +#define EMAC_PHY_BMSR_10BE_HALF (1<<11) /**< 10 base T half duplex */ +#define EMAC_PHY_BMSR_NOPREAM (1<<6) /**< MF Preamable Supress */ +#define EMAC_PHY_BMSR_AUTO_DONE (1<<5) /**< Auto negotiation complete */ +#define EMAC_PHY_BMSR_REMOTE_FAULT (1<<4) /**< Remote fault */ +#define EMAC_PHY_BMSR_NO_AUTO (1<<3) /**< Auto Negotiation ability */ +#define EMAC_PHY_BMSR_LINK_ESTABLISHED (1<<2) /**< Link status */ + +/*********************************************************************//** + * Macro defines for PHY Status Register + **********************************************************************/ +#define EMAC_PHY_SR_REMOTE_FAULT (1<<6) /**< Remote Fault */ +#define EMAC_PHY_SR_JABBER (1<<5) /**< Jabber detect */ +#define EMAC_PHY_SR_AUTO_DONE (1<<4) /**< Auto Negotiation complete */ +#define EMAC_PHY_SR_LOOPBACK (1<<3) /**< Loop back status */ +#define EMAC_PHY_SR_DUP (1<<2) /**< Duplex status */ +#define EMAC_PHY_SR_SPEED (1<<1) /**< Speed status */ +#define EMAC_PHY_SR_LINK (1<<0) /**< Link Status */ + +#define EMAC_PHY_FULLD_100M 0x2100 /**< Full Duplex 100Mbit */ +#define EMAC_PHY_HALFD_100M 0x2000 /**< Half Duplex 100Mbit */ +#define EMAC_PHY_FULLD_10M 0x0100 /**< Full Duplex 10Mbit */ +#define EMAC_PHY_HALFD_10M 0x0000 /**< Half Duplex 10MBit */ +#define EMAC_PHY_AUTO_NEG 0x3000 /**< Select Auto Negotiation */ + +#define EMAC_DEF_ADR 0x0100 /**< Default PHY device address */ +#define EMAC_DP83848C_ID 0x20005C90 /**< PHY Identifier */ + +#define EMAC_PHY_SR_100_SPEED ((1<<14)|(1<<13)) +#define EMAC_PHY_SR_FULL_DUP ((1<<14)|(1<<12)) +#define EMAC_PHY_BMSR_LINK_STATUS (1<<2) /**< Link status */ + +#elif defined(IAR_LPC_1768) +/* KSZ8721BL PHY definition ------------------------------------------------------------ */ +/** PHY device reset time out definition */ +#define EMAC_PHY_RESP_TOUT 0x100000UL + +/* ENET Device Revision ID */ +#define EMAC_OLD_EMAC_MODULE_ID 0x39022000 /**< Rev. ID for first rev '-' */ + +/*********************************************************************//** + * Macro defines for KSZ8721BL PHY Registers + **********************************************************************/ +#define EMAC_PHY_REG_BMCR 0x00 /**< Basic Mode Control Register */ +#define EMAC_PHY_REG_BMSR 0x01 /**< Basic Mode Status Register */ +#define EMAC_PHY_REG_IDR1 0x02 /**< PHY Identifier 1 */ +#define EMAC_PHY_REG_IDR2 0x03 /**< PHY Identifier 2 */ +#define EMAC_PHY_REG_ANAR 0x04 /**< Auto-Negotiation Advertisement */ +#define EMAC_PHY_REG_ANLPAR 0x05 /**< Auto-Neg. Link Partner Abitily */ +#define EMAC_PHY_REG_ANER 0x06 /**< Auto-Neg. Expansion Register */ +#define EMAC_PHY_REG_ANNPTR 0x07 /**< Auto-Neg. Next Page TX */ +#define EMAC_PHY_REG_LPNPA 0x08 /**< Link Partner Next Page Ability */ +#define EMAC_PHY_REG_REC 0x15 /**< RXError Counter Register */ +#define EMAC_PHY_REG_ISC 0x1b /**< Interrupt Control/Status Register */ +#define EMAC_PHY_REG_100BASE 0x1f /**< 100BASE-TX PHY Control Register */ + +/*********************************************************************//** + * Macro defines for PHY Basic Mode Control Register + **********************************************************************/ +#define EMAC_PHY_BMCR_RESET (1<<15) /**< Reset bit */ +#define EMAC_PHY_BMCR_LOOPBACK (1<<14) /**< Loop back */ +#define EMAC_PHY_BMCR_SPEED_SEL (1<<13) /**< Speed selection */ +#define EMAC_PHY_BMCR_AN (1<<12) /**< Auto Negotiation */ +#define EMAC_PHY_BMCR_POWERDOWN (1<<11) /**< Power down mode */ +#define EMAC_PHY_BMCR_ISOLATE (1<<10) /**< Isolate */ +#define EMAC_PHY_BMCR_RE_AN (1<<9) /**< Restart auto negotiation */ +#define EMAC_PHY_BMCR_DUPLEX (1<<8) /**< Duplex mode */ +#define EMAC_PHY_BMCR_COLLISION (1<<7) /**< Collision test */ +#define EMAC_PHY_BMCR_TXDIS (1<<0) /**< Disable transmit */ + +/*********************************************************************//** + * Macro defines for PHY Basic Mode Status Register + **********************************************************************/ +#define EMAC_PHY_BMSR_100BE_T4 (1<<15) /**< 100 base T4 */ +#define EMAC_PHY_BMSR_100TX_FULL (1<<14) /**< 100 base full duplex */ +#define EMAC_PHY_BMSR_100TX_HALF (1<<13) /**< 100 base half duplex */ +#define EMAC_PHY_BMSR_10BE_FULL (1<<12) /**< 10 base T full duplex */ +#define EMAC_PHY_BMSR_10BE_HALF (1<<11) /**< 10 base T half duplex */ +#define EMAC_PHY_BMSR_NOPREAM (1<<6) /**< MF Preamable Supress */ +#define EMAC_PHY_BMSR_AUTO_DONE (1<<5) /**< Auto negotiation complete */ +#define EMAC_PHY_BMSR_REMOTE_FAULT (1<<4) /**< Remote fault */ +#define EMAC_PHY_BMSR_NO_AUTO (1<<3) /**< Auto Negotiation ability */ +#define EMAC_PHY_BMSR_LINK_STATUS (1<<2) /**< Link status */ +#define EMAC_PHY_BMSR_JABBER_DETECT (1<<1) /**< Jabber detect */ +#define EMAC_PHY_BMSR_EXTEND (1<<0) /**< Extended support */ + +/*********************************************************************//** + * Macro defines for PHY Identifier + **********************************************************************/ +/* PHY Identifier 1 bitmap definitions */ +#define EMAC_PHY_IDR1(n) (n & 0xFFFF) /**< PHY ID1 Number */ + +/* PHY Identifier 2 bitmap definitions */ +#define EMAC_PHY_IDR2(n) (n & 0xFFFF) /**< PHY ID2 Number */ + +/*********************************************************************//** + * Macro defines for Auto-Negotiation Advertisement + **********************************************************************/ +#define EMAC_PHY_AN_NEXTPAGE (1<<15) /**< Next page capable */ +#define EMAC_PHY_AN_REMOTE_FAULT (1<<13) /**< Remote Fault support */ +#define EMAC_PHY_AN_PAUSE (1<<10) /**< Pause support */ +#define EMAC_PHY_AN_100BASE_T4 (1<<9) /**< T4 capable */ +#define EMAC_PHY_AN_100BASE_TX_FD (1<<8) /**< TX with Full-duplex capable */ +#define EMAC_PHY_AN_100BASE_TX (1<<7) /**< TX capable */ +#define EMAC_PHY_AN_10BASE_T_FD (1<<6) /**< 10Mbps with full-duplex capable */ +#define EMAC_PHY_AN_10BASE_T (1<<5) /**< 10Mbps capable */ +#define EMAC_PHY_AN_FIELD(n) (n & 0x1F) /**< Selector Field */ + +#define EMAC_PHY_FULLD_100M 0x2100 /**< Full Duplex 100Mbit */ +#define EMAC_PHY_HALFD_100M 0x2000 /**< Half Duplex 100Mbit */ +#define EMAC_PHY_FULLD_10M 0x0100 /**< Full Duplex 10Mbit */ +#define EMAC_PHY_HALFD_10M 0x0000 /**< Half Duplex 10MBit */ +#define EMAC_PHY_AUTO_NEG 0x3000 /**< Select Auto Negotiation */ + +#define EMAC_PHY_SR_100_SPEED ((1<<14)|(1<<13)) +#define EMAC_PHY_SR_FULL_DUP ((1<<14)|(1<<12)) + +#define EMAC_DEF_ADR (0x01<<8) /**< Default PHY device address */ +#define EMAC_KSZ8721BL_ID ((0x22 << 16) | 0x1619 ) /**< PHY Identifier */ +#endif + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup EMAC_Public_Types EMAC Public Types + * @{ + */ + +/* Descriptor and status formats ---------------------------------------------- */ + +/** + * @brief RX Descriptor structure type definition + */ +typedef struct { + uint32_t Packet; /**< Receive Packet Descriptor */ + uint32_t Ctrl; /**< Receive Control Descriptor */ +} RX_Desc; + +/** + * @brief RX Status structure type definition + */ +typedef struct { + uint32_t Info; /**< Receive Information Status */ + uint32_t HashCRC; /**< Receive Hash CRC Status */ +} RX_Stat; + +/** + * @brief TX Descriptor structure type definition + */ +typedef struct { + uint32_t Packet; /**< Transmit Packet Descriptor */ + uint32_t Ctrl; /**< Transmit Control Descriptor */ +} TX_Desc; + +/** + * @brief TX Status structure type definition + */ +typedef struct { + uint32_t Info; /**< Transmit Information Status */ +} TX_Stat; + + +/** + * @brief TX Data Buffer structure definition + */ +typedef struct { + uint32_t ulDataLen; /**< Data length */ + uint32_t *pbDataBuf; /**< A word-align data pointer to data buffer */ +} EMAC_PACKETBUF_Type; + +/** + * @brief EMAC configuration structure definition + */ +typedef struct { + uint32_t Mode; /**< Supported EMAC PHY device speed, should be one of the following: + - EMAC_MODE_AUTO + - EMAC_MODE_10M_FULL + - EMAC_MODE_10M_HALF + - EMAC_MODE_100M_FULL + - EMAC_MODE_100M_HALF + */ + uint8_t *pbEMAC_Addr; /**< Pointer to EMAC Station address that contains 6-bytes + of MAC address, it must be sorted in order (bEMAC_Addr[0]..[5]) + */ +} EMAC_CFG_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup EMAC_Public_Functions EMAC Public Functions + * @{ + */ +/* Init/DeInit EMAC peripheral */ +Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct); +void EMAC_DeInit(void); + +/* PHY functions --------------*/ +int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState); +int32_t EMAC_SetPHYMode(uint32_t ulPHYMode); +int32_t EMAC_UpdatePHYStatus(void); + +/* Filter functions ----------*/ +void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState); +void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState); + +/* EMAC Packet Buffer functions */ +void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct); +void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct); + +/* EMAC Interrupt functions -------*/ +void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState); +IntStatus EMAC_IntGetStatus(uint32_t ulIntType); + +/* EMAC Index functions -----------*/ +Bool EMAC_CheckReceiveIndex(void); +Bool EMAC_CheckTransmitIndex(void); +void EMAC_UpdateRxConsumeIndex(void); +void EMAC_UpdateTxProduceIndex(void); + +FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType); +uint32_t EMAC_GetReceiveDataSize(void); +FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_EMAC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_exti.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_exti.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,158 @@ +/** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_exti.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_exti.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,143 @@ +/***********************************************************************//** + * @file lpc17xx_exti.h + * @brief Contains all macro definitions and function prototypes + * support for External interrupt firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup EXTI EXTI + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_EXTI_H_ +#define LPC17XX_EXTI_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup EXTI_Private_Macros EXTI Private Macros + * @{ + */ +/*********************************************************************//** + * Macro defines for EXTI control register + **********************************************************************/ +#define EXTI_EINT0_BIT_MARK 0x01 +#define EXTI_EINT1_BIT_MARK 0x02 +#define EXTI_EINT2_BIT_MARK 0x04 +#define EXTI_EINT3_BIT_MARK 0x08 + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup EXTI_Public_Types EXTI Public Types + * @{ + */ + +/** + * @brief EXTI external interrupt line option + */ +typedef enum +{ + EXTI_EINT0, /*!< External interrupt 0, P2.10 */ + EXTI_EINT1, /*!< External interrupt 0, P2.11 */ + EXTI_EINT2, /*!< External interrupt 0, P2.12 */ + EXTI_EINT3 /*!< External interrupt 0, P2.13 */ +} EXTI_LINE_ENUM; + +/** + * @brief EXTI mode option + */ +typedef enum +{ + EXTI_MODE_LEVEL_SENSITIVE, /*!< Level sensitivity is selected */ + EXTI_MODE_EDGE_SENSITIVE /*!< Edge sensitivity is selected */ +} EXTI_MODE_ENUM; + +/** + * @brief EXTI polarity option + */ +typedef enum +{ + EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE, /*!< Low active or falling edge sensitive + depending on pin mode */ + EXTI_POLARITY_HIGH_ACTIVE_OR_RISING_EDGE /*!< High active or rising edge sensitive + depending on pin mode */ +} EXTI_POLARITY_ENUM; + +/** + * @brief EXTI Initialize structure + */ +typedef struct +{ + EXTI_LINE_ENUM EXTI_Line; /*!<Select external interrupt pin (EINT0, EINT1, EINT 2, EINT3) */ + + EXTI_MODE_ENUM EXTI_Mode; /*!< Choose between Level-sensitivity or Edge sensitivity */ + + EXTI_POLARITY_ENUM EXTI_polarity; /*!< If EXTI mode is level-sensitive: this element use to select low or high active level + if EXTI mode is polarity-sensitive: this element use to select falling or rising edge */ + +}EXTI_InitTypeDef; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup EXTI_Public_Functions EXTI Public Functions + * @{ + */ + +void EXTI_Init(void); +void EXTI_DeInit(void); + +void EXTI_Config(EXTI_InitTypeDef *EXTICfg); +void EXTI_SetMode(EXTI_LINE_ENUM EXTILine, EXTI_MODE_ENUM mode); +void EXTI_SetPolarity(EXTI_LINE_ENUM EXTILine, EXTI_POLARITY_ENUM polarity); +void EXTI_ClearEXTIFlag(EXTI_LINE_ENUM EXTILine); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC17XX_EXTI_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_gpdma.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_gpdma.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,433 @@ +/** + * @file : lpc17xx_gpdma.c + * @brief : Contains all functions support for GPDMA firmware library on LPC17xx + * @version : 1.0 + * @date : 20. Apr. 2009 + * @author : HieuNguyen + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 + * @{ + */ + +/** + * @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_4, // 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 +}; + +/** Interrupt Call-back function pointer data for each GPDMA channel */ +static fnGPDMACbs_Type *_apfnGPDMACbs[8] = { + NULL, // GPDMA Call-back function pointer for Channel 0 + NULL, // GPDMA Call-back function pointer for Channel 1 + NULL, // GPDMA Call-back function pointer for Channel 2 + NULL, // GPDMA Call-back function pointer for Channel 3 + NULL, // GPDMA Call-back function pointer for Channel 4 + NULL, // GPDMA Call-back function pointer for Channel 5 + NULL, // GPDMA Call-back function pointer for Channel 6 + NULL, // GPDMA Call-back function pointer for Channel 7 +}; + +/** + * @} + */ + +/* 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. + * @param[in] pfnGPDMACbs Pointer to a GPDMA interrupt call-back function + * @return ERROR if selected channel is enabled before + * or SUCCESS if channel is configured successfully + *********************************************************************/ +Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig, fnGPDMACbs_Type *pfnGPDMACbs) +{ + 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]; + + // Setup call back function for this channel + _apfnGPDMACbs[GPDMAChannelConfig->ChannelNum] = pfnGPDMACbs; + + // 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->RESERVED9 |= (1<<(GPDMAChannelConfig->SrcConn - 16)); + } else { + LPC_SC->RESERVED9 &= ~(1<<(GPDMAChannelConfig->SrcConn - 8)); + } + + /* Re-Configure DMA Request Select for Destination peripheral */ + if (GPDMAChannelConfig->DstConn > 15) + { + LPC_SC->RESERVED9 |= (1<<(GPDMAChannelConfig->DstConn - 16)); + } else { + LPC_SC->RESERVED9 &= ~(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 Standard GPDMA interrupt handler, this function will check + * all interrupt status of GPDMA channels, then execute the call + * back function id they're already installed + * @param[in] None + * @return None + **********************************************************************/ +void GPDMA_IntHandler(void) +{ + uint32_t tmp; + // Scan interrupt pending + for (tmp = 0; tmp <= 7; tmp++) { + if (LPC_GPDMA->DMACIntStat & GPDMA_DMACIntStat_Ch(tmp)) { + // Check counter terminal status + if (LPC_GPDMA->DMACIntTCStat & GPDMA_DMACIntTCStat_Ch(tmp)) { + // Clear terminate counter Interrupt pending + LPC_GPDMA->DMACIntTCClear = GPDMA_DMACIntTCClear_Ch(tmp); + // Execute call-back function if it is already installed + if(_apfnGPDMACbs[tmp] != NULL) { + _apfnGPDMACbs[tmp](GPDMA_STAT_INTTC); + } + } + // Check error terminal status + if (LPC_GPDMA->DMACIntErrStat & GPDMA_DMACIntErrStat_Ch(tmp)) { + // Clear error counter Interrupt pending + LPC_GPDMA->DMACIntErrClr = GPDMA_DMACIntErrClr_Ch(tmp); + // Execute call-back function if it is already installed + if(_apfnGPDMACbs[tmp] != NULL) { + _apfnGPDMACbs[tmp](GPDMA_STAT_INTERR); + } + } + } + } +} + + +/** + * @} + */ + +#endif /* _GPDMA */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_gpdma.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_gpdma.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,394 @@ +/***********************************************************************//** + * @file : lpc17xx_gpdma.h + * @brief : Contains all macro definitions and function prototypes + * support for GPDMA firmware library on LPC17xx + * @version : 1.0 + * @date : 20. Apr. 2009 + * @author : HieuNguyen + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup GPDMA + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_GPDMA_H_ +#define LPC17XX_GPDMA_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "cmsis.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup GPDMA_Private_Macros + * @{ + */ + +/** @defgroup DMA_REGISTER_BIT_DEFINITIONS + * @{ + */ + +/** Macros define for DMA interrupt */ +/** DMA Interrupt Status register */ +#define GPDMA_DMACIntStat_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACIntStat_BITMASK ((0xFF)) + +/** DMA Interrupt Terminal Count Request Status register */ +#define GPDMA_DMACIntTCStat_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACIntTCStat_BITMASK ((0xFF)) + +/** DMA Interrupt Terminal Count Request Clear register */ +#define GPDMA_DMACIntTCClear_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACIntTCClear_BITMASK ((0xFF)) + +/** DMA Interrupt Error Status register */ +#define GPDMA_DMACIntErrStat_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACIntErrStat_BITMASK ((0xFF)) + +/** DMA Interrupt Error Clear register */ +#define GPDMA_DMACIntErrClr_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACIntErrClr_BITMASK ((0xFF)) + +/** DMA Raw Interrupt Terminal Count Status register */ +#define GPDMA_DMACRawIntTCStat_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACRawIntTCStat_BITMASK ((0xFF)) + +/** DMA Raw Error Interrupt Status register */ +#define GPDMA_DMACRawIntErrStat_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACRawIntErrStat_BITMASK ((0xFF)) + +/** DMA Enabled Channel register */ +#define GPDMA_DMACEnbldChns_Ch(n) (((1UL<<n)&0xFF)) +#define GPDMA_DMACEnbldChns_BITMASK ((0xFF)) + + +/** Macro defines for DMA Software Burst Request register */ +#define GPDMA_DMACSoftBReq_Src(n) (((1UL<<n)&0xFFFF)) +#define GPDMA_DMACSoftBReq_BITMASK ((0xFFFF)) + +/** Macro defines for DMA Software Single Request register */ +#define GPDMA_DMACSoftSReq_Src(n) (((1UL<<n)&0xFFFF)) +#define GPDMA_DMACSoftSReq_BITMASK ((0xFFFF)) + +/** Macro defines for DMA Software Last Burst Request register */ +#define GPDMA_DMACSoftLBReq_Src(n) (((1UL<<n)&0xFFFF)) +#define GPDMA_DMACSoftLBReq_BITMASK ((0xFFFF)) + +/** Macro defines for DMA Software Last Single Request register */ +#define GPDMA_DMACSoftLSReq_Src(n) (((1UL<<n)&0xFFFF)) +#define GPDMA_DMACSoftLSReq_BITMASK ((0xFFFF)) + +/** DMA Configuration register bit description*/ +#define GPDMA_DMACConfig_E ((0x01)) /**< DMA Controller enable*/ +#define GPDMA_DMACConfig_M ((0x02)) /**< AHB Master endianness configuration*/ +#define GPDMA_DMACConfig_BITMASK ((0x03)) + + +/** Macro defines for DMA Synchronization register */ +#define GPDMA_DMACSync_Src(n) (((1UL<<n)&0xFFFF)) +#define GPDMA_DMACSync_BITMASK ((0xFFFF)) + +/** Macro defines for DMA Request Select register */ +#define GPDMA_DMAReqSel_Input(n) (((1UL<<(n-8))&0xFF)) +#define GPDMA_DMAReqSel_BITMASK ((0xFF)) + +/** DMA Channel Linked List Item registers bit mask*/ +#define GPDMA_DMACCxLLI_BITMASK ((0xFFFFFFFC)) + +/** DMA channel control registers bit description */ +#define GPDMA_DMACCxControl_TransferSize(n) (((n&0xFFF)<<0)) /**< Transfer size*/ +#define GPDMA_DMACCxControl_SBSize(n) (((n&0x07)<<12)) /**< Source burst size*/ +#define GPDMA_DMACCxControl_DBSize(n) (((n&0x07)<<15)) /**< Destination burst size*/ +#define GPDMA_DMACCxControl_SWidth(n) (((n&0x07)<<18)) /**< Source transfer width*/ +#define GPDMA_DMACCxControl_DWidth(n) (((n&0x07)<<21)) /**< Destination transfer width*/ +#define GPDMA_DMACCxControl_SI ((1UL<<26)) /**< Source increment*/ +#define GPDMA_DMACCxControl_DI ((1UL<<27)) /**< Destination increment*/ +#define GPDMA_DMACCxControl_Prot1 ((1UL<<28)) /**< Indicates that the access is in user mode or privileged mode*/ +#define GPDMA_DMACCxControl_Prot2 ((1UL<<29)) /**< Indicates that the access is bufferable or not bufferable*/ +#define GPDMA_DMACCxControl_Prot3 ((1UL<<30)) /**< Indicates that the access is cacheable or not cacheable*/ +#define GPDMA_DMACCxControl_I ((1UL<<31)) /**< Terminal count interrupt enable bit */ +/** DMA channel control registers bit mask */ +#define GPDMA_DMACCxControl_BITMASK ((0xFCFFFFFF)) + + +/** DMA Channel Configuration registers bit description*/ +#define GPDMA_DMACCxConfig_E ((1UL<<0)) /**< DMA control enable*/ +#define GPDMA_DMACCxConfig_SrcPeripheral(n) (((n&0x1F)<<1)) /**< Source peripheral*/ +#define GPDMA_DMACCxConfig_DestPeripheral(n) (((n&0x1F)<<6)) /**< Destination peripheral*/ +#define GPDMA_DMACCxConfig_TransferType(n) (((n&0x7)<<11)) /**< This value indicates the type of transfer*/ +#define GPDMA_DMACCxConfig_IE ((1UL<<14)) /**< Interrupt error mask*/ +#define GPDMA_DMACCxConfig_ITC ((1UL<<15)) /**< Terminal count interrupt mask*/ +#define GPDMA_DMACCxConfig_L ((1UL<<16)) /**< Lock*/ +#define GPDMA_DMACCxConfig_A ((1UL<<17)) /**< Active*/ +#define GPDMA_DMACCxConfig_H ((1UL<<18)) /**< Halt*/ +/** DMA Channel Configuration registers bit mask */ +#define GPDMA_DMACCxConfig_BITMASK ((0x7FFFF)) + + +/** + * @} + */ + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup GPDMA_Public_Types + * @{ + */ + + +/** + * @brief GPDMA Channel configuration structure type definition + */ +typedef struct { + uint32_t ChannelNum; /**< DMA channel number, should be in + range from 0 to 7. + Note: DMA channel 0 has the highest priority + and DMA channel 7 the lowest priority. + */ + uint32_t TransferSize; /**< Length/Size of transfer */ + uint32_t TransferWidth; /**< Transfer width - used for TransferType is GPDMA_TRANSFERTYPE_M2M only */ + uint32_t SrcMemAddr; /**< Physical Source Address, used in case TransferType is chosen as + GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_M2P */ + uint32_t DstMemAddr; /**< Physical Destination Address, used in case TransferType is chosen as + GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_P2M */ + uint32_t TransferType; /**< Transfer Type, should be one of the following: + - GPDMA_TRANSFERTYPE_M2M: Memory to memory - DMA control + - GPDMA_TRANSFERTYPE_M2P: Memory to peripheral - DMA control + - GPDMA_TRANSFERTYPE_P2M: Peripheral to memory - DMA control + - GPDMA_TRANSFERTYPE_P2P: Source peripheral to destination peripheral - DMA control + */ + uint32_t SrcConn; /**< Peripheral Source Connection type, used in case TransferType is chosen as + GPDMA_TRANSFERTYPE_P2M or GPDMA_TRANSFERTYPE_P2P, should be one of + following: + - GPDMA_CONN_SSP0_Tx: SSP0, Tx + - GPDMA_CONN_SSP0_Rx: SSP0, Rx + - GPDMA_CONN_SSP1_Tx: SSP1, Tx + - GPDMA_CONN_SSP1_Rx: SSP1, Rx + - GPDMA_CONN_ADC: ADC + - GPDMA_CONN_I2S_Channel_0: I2S Channel 0 + - GPDMA_CONN_I2S_Channel_1: I2S Channel 1 + - GPDMA_CONN_DAC: DAC + - GPDMA_CONN_UART0_Tx_MAT0_0: UART0 Tx / MAT0.0 + - GPDMA_CONN_UART0_Rx_MAT0_1: UART0 Rx / MAT0.1 + - GPDMA_CONN_UART1_Tx_MAT1_0: UART1 Tx / MAT1.0 + - GPDMA_CONN_UART1_Rx_MAT1_1: UART1 Rx / MAT1.1 + - GPDMA_CONN_UART2_Tx_MAT2_0: UART2 Tx / MAT2.0 + - GPDMA_CONN_UART2_Rx_MAT2_1: UART2 Rx / MAT2.1 + - GPDMA_CONN_UART3_Tx_MAT3_0: UART3 Tx / MAT3.0 + - GPDMA_CONN_UART3_Rx_MAT3_1: UART3 Rx / MAT3.1 + */ + uint32_t DstConn; /**< Peripheral Destination Connection type, used in case TransferType is chosen as + GPDMA_TRANSFERTYPE_M2P or GPDMA_TRANSFERTYPE_P2P, should be one of + following: + - GPDMA_CONN_SSP0_Tx: SSP0, Tx + - GPDMA_CONN_SSP0_Rx: SSP0, Rx + - GPDMA_CONN_SSP1_Tx: SSP1, Tx + - GPDMA_CONN_SSP1_Rx: SSP1, Rx + - GPDMA_CONN_ADC: ADC + - GPDMA_CONN_I2S_Channel_0: I2S Channel 0 + - GPDMA_CONN_I2S_Channel_1: I2S Channel 1 + - GPDMA_CONN_DAC: DAC + - GPDMA_CONN_UART0_Tx_MAT0_0: UART0 Tx / MAT0.0 + - GPDMA_CONN_UART0_Rx_MAT0_1: UART0 Rx / MAT0.1 + - GPDMA_CONN_UART1_Tx_MAT1_0: UART1 Tx / MAT1.0 + - GPDMA_CONN_UART1_Rx_MAT1_1: UART1 Rx / MAT1.1 + - GPDMA_CONN_UART2_Tx_MAT2_0: UART2 Tx / MAT2.0 + - GPDMA_CONN_UART2_Rx_MAT2_1: UART2 Rx / MAT2.1 + - GPDMA_CONN_UART3_Tx_MAT3_0: UART3 Tx / MAT3.0 + - GPDMA_CONN_UART3_Rx_MAT3_1: UART3 Rx / MAT3.1 + */ + uint32_t DMALLI; /**< Linker List Item structure data address + if there's no Linker List, set as '0' + */ +} GPDMA_Channel_CFG_Type; + + +/** + * @brief GPDMA Linker List Item structure type definition + */ +typedef struct { + uint32_t SrcAddr; /**< Source Address */ + uint32_t DstAddr; /**< Destination address */ + uint32_t NextLLI; /**< Next LLI address, otherwise set to '0' */ + uint32_t Control; /**< GPDMA Control of this LLI */ +} GPDMA_LLI_Type; + + +/** GPDMA call-back function type definitions */ +typedef void (fnGPDMACbs_Type)(uint32_t channelStatus); + + +/** + * @} + */ + + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup GPDMA_Public_Macros + * @{ + */ + +#define PARAM_GPDMA_CHANNEL(n) ((n>=0) && (n<=7)) + +/** DMA Connection number definitions */ +#define GPDMA_CONN_SSP0_Tx ((0UL)) /**< SSP0 Tx */ +#define GPDMA_CONN_SSP0_Rx ((1UL)) /**< SSP0 Rx */ +#define GPDMA_CONN_SSP1_Tx ((2UL)) /**< SSP1 Tx */ +#define GPDMA_CONN_SSP1_Rx ((3UL)) /**< SSP1 Rx */ +#define GPDMA_CONN_ADC ((4UL)) /**< ADC */ +#define GPDMA_CONN_I2S_Channel_0 ((5UL)) /**< I2S channel 0 */ +#define GPDMA_CONN_I2S_Channel_1 ((6UL)) /**< I2S channel 1 */ +#define GPDMA_CONN_DAC ((7UL)) /**< DAC */ +#define GPDMA_CONN_UART0_Tx ((8UL)) /**< UART0 Tx */ +#define GPDMA_CONN_UART0_Rx ((9UL)) /**< UART0 Rx */ +#define GPDMA_CONN_UART1_Tx ((10UL)) /**< UART1 Tx */ +#define GPDMA_CONN_UART1_Rx ((11UL)) /**< UART1 Rx */ +#define GPDMA_CONN_UART2_Tx ((12UL)) /**< UART2 Tx */ +#define GPDMA_CONN_UART2_Rx ((13UL)) /**< UART2 Rx */ +#define GPDMA_CONN_UART3_Tx ((14UL)) /**< UART3 Tx */ +#define GPDMA_CONN_UART3_Rx ((15UL)) /**< UART3 Rx */ +#define GPDMA_CONN_MAT0_0 ((16UL)) /**< MAT0.0 */ +#define GPDMA_CONN_MAT0_1 ((17UL)) /**< MAT0.1 */ +#define GPDMA_CONN_MAT1_0 ((18UL)) /**< MAT1.0 */ +#define GPDMA_CONN_MAT1_1 ((19UL)) /**< MAT1.1 */ +#define GPDMA_CONN_MAT2_0 ((20UL)) /**< MAT2.0 */ +#define GPDMA_CONN_MAT2_1 ((21UL)) /**< MAT2.1 */ +#define GPDMA_CONN_MAT3_0 ((22UL)) /**< MAT3.0 */ +#define GPDMA_CONN_MAT3_1 ((23UL)) /**< MAT3.1 */ + +#define PARAM_GPDMA_CONN(n) ((n==GPDMA_CONN_SSP0_Tx) || (n==GPDMA_CONN_SSP0_Rx) \ +|| (n==GPDMA_CONN_SSP1_Tx) || (n==GPDMA_CONN_SSP1_Rx) \ +|| (n==GPDMA_CONN_ADC) || (n==GPDMA_CONN_I2S_Channel_0) \ +|| (n==GPDMA_CONN_I2S_Channel_1) || (n==GPDMA_CONN_DAC) \ +|| (n==GPDMA_CONN_UART0_Tx) || (n==GPDMA_CONN_UART0_Rx) \ +|| (n==GPDMA_CONN_UART1_Tx) || (n==GPDMA_CONN_UART1_Rx) \ +|| (n==GPDMA_CONN_UART2_Tx) || (n==GPDMA_CONN_UART2_Rx) \ +|| (n==GPDMA_CONN_UART3_Tx) || (n==GPDMA_CONN_UART3_Rx) \ +|| (n==GPDMA_CONN_MAT0_0) || (n==GPDMA_CONN_MAT0_1) \ +|| (n==GPDMA_CONN_MAT1_0) || (n==GPDMA_CONN_MAT1_1) \ +|| (n==GPDMA_CONN_MAT2_0) || (n==GPDMA_CONN_MAT2_1) \ +|| (n==GPDMA_CONN_MAT3_0) || (n==GPDMA_CONN_MAT3_1)) + + +/** GPDMA Transfer type definitions */ +#define GPDMA_TRANSFERTYPE_M2M ((0UL)) /**< Memory to memory - DMA control */ +#define GPDMA_TRANSFERTYPE_M2P ((1UL)) /**< Memory to peripheral - DMA control */ +#define GPDMA_TRANSFERTYPE_P2M ((2UL)) /**< Peripheral to memory - DMA control */ +#define GPDMA_TRANSFERTYPE_P2P ((3UL)) /**< Source peripheral to destination peripheral - DMA control */ + + +#define PARAM_GPDMA_TRANSFERTYPE(n) ((n==GPDMA_TRANSFERTYPE_M2M)||(n==GPDMA_TRANSFERTYPE_M2P) \ +||(n==GPDMA_TRANSFERTYPE_P2M)||(n==GPDMA_TRANSFERTYPE_P2P)) + + +/** Burst size in Source and Destination definitions */ +#define GPDMA_BSIZE_1 ((0UL)) /**< Burst size = 1 */ +#define GPDMA_BSIZE_4 ((1UL)) /**< Burst size = 4 */ +#define GPDMA_BSIZE_8 ((2UL)) /**< Burst size = 8 */ +#define GPDMA_BSIZE_16 ((3UL)) /**< Burst size = 16 */ +#define GPDMA_BSIZE_32 ((4UL)) /**< Burst size = 32 */ +#define GPDMA_BSIZE_64 ((5UL)) /**< Burst size = 64 */ +#define GPDMA_BSIZE_128 ((6UL)) /**< Burst size = 128 */ +#define GPDMA_BSIZE_256 ((7UL)) /**< Burst size = 256 */ + +#define PARAM_GPDMA_BSIZE(n) ((n==GPDMA_BSIZE_1) || (n==GPDMA_BSIZE_4) \ +|| (n==GPDMA_BSIZE_8) || (n==GPDMA_BSIZE_16) \ +|| (n==GPDMA_BSIZE_32) || (n==GPDMA_BSIZE_64) \ +|| (n==GPDMA_BSIZE_128) || (n==GPDMA_BSIZE_256)) + + +/** Width in Source transfer width and Destination transfer width definitions */ +#define GPDMA_WIDTH_BYTE ((0UL)) /**< Width = 1 byte */ +#define GPDMA_WIDTH_HALFWORD ((1UL)) /**< Width = 2 bytes */ +#define GPDMA_WIDTH_WORD ((2UL)) /**< Width = 4 bytes */ + +#define PARAM_GPDMA_WIDTH(n) ((n==GPDMA_WIDTH_BYTE) || (n==GPDMA_WIDTH_HALFWORD) \ +|| (n==GPDMA_WIDTH_WORD)) + + +/** DMA Request Select Mode definitions */ +#define GPDMA_REQSEL_UART ((0UL)) /**< UART TX/RX is selected */ +#define GPDMA_REQSEL_TIMER ((1UL)) /**< Timer match is selected */ + +#define PARAM_GPDMA_REQSEL(n) ((n==GPDMA_REQSEL_UART) || (n==GPDMA_REQSEL_TIMER)) + +/** GPDMA Status type definitions */ +/** GPDMA Interrupt Status */ +#define GPDMA_STAT_INT ((0UL)) +/** GPDMA Interrupt Terminal Count Request Status */ +#define GPDMA_STAT_INTTC ((1UL)) +/** GPDMA Interrupt Error Status */ +#define GPDMA_STAT_INTERR ((2UL)) +/** GPDMA Raw Interrupt Terminal Count Status */ +#define GPDMA_STAT_RAWINTTC ((3UL)) +/** GPDMA Raw Error Interrupt Status */ +#define GPDMA_STAT_RAWINTERR ((4UL)) +/** DMA Enabled Channel Status */ +#define GPDMA_STAT_ENABLED_CH ((5UL)) + +#define PARAM_GPDMA_STAT(n) ((n==GPDMA_STAT_INT) || (n==GPDMA_STAT_INTTC) \ +|| (n==GPDMA_STAT_INTERR) || (n==GPDMA_STAT_RAWINTTC) \ +|| (n==GPDMA_STAT_RAWINTERR) || (n==GPDMA_STAT_ENABLED_CH)) + +/** GPDMA status type definition that can be clear */ +/** GPDMA Interrupt Terminal Count Request Clear */ +#define GPDMA_STATCLR_INTTC ((0UL)) +/** GPDMA Interrupt Error Clear */ +#define GPDMA_STATCLR_INTERR ((1UL)) + +#define GPDMA_STATCLR(n) ((n==GPDMA_STATCLR_INTTC) || (n==GPDMA_STATCLR_INTERR)) + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup GPDMA_Public_Functions + * @{ + */ + +void GPDMA_Init(void); +Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig, fnGPDMACbs_Type *pfnGPDMACbs); +void GPDMA_ChannelCmd(uint8_t channelNum, FunctionalState NewState); +void GPDMA_IntHandler(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_GPDMA_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_gpio.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_gpio.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,749 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = 0;// = 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 = 0;// = 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 = 0;// = 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_gpio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_gpio.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,165 @@ +/***********************************************************************//** + * @file lpc17xx_gpio.h + * @brief Contains all macro definitions and function prototypes + * support for GPIO firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup GPIO GPIO + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_GPIO_H_ +#define LPC17XX_GPIO_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup GPIO_Public_Macros GPIO Public Macros + * @{ + */ + +/** Fast GPIO port 0 byte accessible definition */ +#define GPIO0_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO0_BASE)) +/** Fast GPIO port 1 byte accessible definition */ +#define GPIO1_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO1_BASE)) +/** Fast GPIO port 2 byte accessible definition */ +#define GPIO2_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO2_BASE)) +/** Fast GPIO port 3 byte accessible definition */ +#define GPIO3_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO3_BASE)) +/** Fast GPIO port 4 byte accessible definition */ +#define GPIO4_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO4_BASE)) + + +/** Fast GPIO port 0 half-word accessible definition */ +#define GPIO0_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO0_BASE)) +/** Fast GPIO port 1 half-word accessible definition */ +#define GPIO1_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO1_BASE)) +/** Fast GPIO port 2 half-word accessible definition */ +#define GPIO2_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO2_BASE)) +/** Fast GPIO port 3 half-word accessible definition */ +#define GPIO3_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO3_BASE)) +/** Fast GPIO port 4 half-word accessible definition */ +#define GPIO4_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO4_BASE)) + +/** + * @} + */ + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup GPIO_Public_Types GPIO Public Types + * @{ + */ + +/** + * @brief Fast GPIO port byte type definition + */ +typedef struct { + __IO uint8_t FIODIR[4]; /**< FIO direction register in byte-align */ + uint32_t RESERVED0[3]; /**< Reserved */ + __IO uint8_t FIOMASK[4]; /**< FIO mask register in byte-align */ + __IO uint8_t FIOPIN[4]; /**< FIO pin register in byte align */ + __IO uint8_t FIOSET[4]; /**< FIO set register in byte-align */ + __O uint8_t FIOCLR[4]; /**< FIO clear register in byte-align */ +} GPIO_Byte_TypeDef; + + +/** + * @brief Fast GPIO port half-word type definition + */ +typedef struct { + __IO uint16_t FIODIRL; /**< FIO direction register lower halfword part */ + __IO uint16_t FIODIRU; /**< FIO direction register upper halfword part */ + uint32_t RESERVED0[3]; /**< Reserved */ + __IO uint16_t FIOMASKL; /**< FIO mask register lower halfword part */ + __IO uint16_t FIOMASKU; /**< FIO mask register upper halfword part */ + __IO uint16_t FIOPINL; /**< FIO pin register lower halfword part */ + __IO uint16_t FIOPINU; /**< FIO pin register upper halfword part */ + __IO uint16_t FIOSETL; /**< FIO set register lower halfword part */ + __IO uint16_t FIOSETU; /**< FIO set register upper halfword part */ + __O uint16_t FIOCLRL; /**< FIO clear register lower halfword part */ + __O uint16_t FIOCLRU; /**< FIO clear register upper halfword part */ +} GPIO_HalfWord_TypeDef; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup GPIO_Public_Functions GPIO Public Functions + * @{ + */ + +/* GPIO style ------------------------------- */ +void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir); +void GPIO_SetValue(uint8_t portNum, uint32_t bitValue); +void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue); +uint32_t GPIO_ReadValue(uint8_t portNum); +void GPIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState); +FunctionalState GPIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState); +void GPIO_ClearInt(uint8_t portNum, uint32_t bitValue); + +/* FIO (word-accessible) style ------------------------------- */ +void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir); +void FIO_SetValue(uint8_t portNum, uint32_t bitValue); +void FIO_ClearValue(uint8_t portNum, uint32_t bitValue); +uint32_t FIO_ReadValue(uint8_t portNum); +void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue); +void FIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState); +FunctionalState FIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState); +void FIO_ClearInt(uint8_t portNum, uint32_t pinNum); + +/* FIO (halfword-accessible) style ------------------------------- */ +void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir); +void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue); +void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue); +void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue); +uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum); + +/* FIO (byte-accessible) style ------------------------------- */ +void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir); +void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue); +void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue); +void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue); +uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_GPIO_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_i2c.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_i2c.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,1373 @@ +/***********************************************************************//** + * @file lpc17xx_i2c.c + * @brief Contains all functions support for I2C firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup I2C + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_i2c.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 _I2C + + +/* Private Types -------------------------------------------------------------- */ +/** @defgroup I2C_Private_Types I2C Private Types + * @{ + */ + +/** + * @brief I2C device configuration structure type + */ +typedef struct +{ + uint32_t txrx_setup; /* Transmission setup */ + int32_t dir; /* Current direction phase, 0 - write, 1 - read */ +} I2C_CFG_T; + +/** + * @} + */ + +/* Private Variables ---------------------------------------------------------- */ +/** + * @brief II2C driver data for I2C0, I2C1 and I2C2 + */ +static I2C_CFG_T i2cdat[3]; + +static uint32_t I2C_MasterComplete[3]; +static uint32_t I2C_SlaveComplete[3]; + +static uint32_t I2C_MonitorBufferIndex; + +/* Private Functions ---------------------------------------------------------- */ + +/* Get I2C number */ +static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx); + +/* Generate a start condition on I2C bus (in master mode only) */ +static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx); + +/* Generate a stop condition on I2C bus (in master mode only) */ +static void I2C_Stop (LPC_I2C_TypeDef *I2Cx); + +/* I2C send byte subroutine */ +static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte); + +/* I2C get byte subroutine */ +static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack); + +/* I2C set clock (hz) */ +static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock); + +/*--------------------------------------------------------------------------------*/ +/********************************************************************//** + * @brief Convert from I2C peripheral to number + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return I2C number, could be: 0..2 + *********************************************************************/ +static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx){ + if (I2Cx == LPC_I2C0) { + return (0); + } else if (I2Cx == LPC_I2C1) { + return (1); + } else if (I2Cx == LPC_I2C2) { + return (2); + } + return (-1); +} + +/********************************************************************//** + * @brief Generate a start condition on I2C bus (in master mode only) + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return value of I2C status register after generate a start condition + *********************************************************************/ +static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx) +{ + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + I2Cx->I2CONSET = I2C_I2CONSET_STA; + + // Wait for complete + while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); +} + +/********************************************************************//** + * @brief Generate a stop condition on I2C bus (in master mode only) + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + *********************************************************************/ +static void I2C_Stop (LPC_I2C_TypeDef *I2Cx) +{ + + /* Make sure start bit is not active */ + if (I2Cx->I2CONSET & I2C_I2CONSET_STA) + { + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + } + I2Cx->I2CONSET = I2C_I2CONSET_STO; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; +} + +/********************************************************************//** + * @brief Send a byte + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] databyte: number of byte + * @return value of I2C status register after sending + *********************************************************************/ +static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte) +{ + /* Make sure start bit is not active */ + if (I2Cx->I2CONSET & I2C_I2CONSET_STA) + { + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + } + I2Cx->I2DAT = databyte & I2C_I2DAT_BITMASK; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + + while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); + return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); +} + +/********************************************************************//** + * @brief Get a byte + * @param[in] I2Cx: I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[out] retdat pointer to return data + * @param[in] ack assert acknowledge or not, should be: TRUE/FALSE + * @return value of I2C status register after sending + *********************************************************************/ +static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack) +{ + if (ack == TRUE) + { + I2Cx->I2CONSET = I2C_I2CONSET_AA; + } + else + { + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; + } + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + + while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); + *retdat = (uint8_t) (I2Cx->I2DAT & I2C_I2DAT_BITMASK); + return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); +} + +/*********************************************************************//** + * @brief Setup clock rate for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] target_clock : clock of SSP (Hz) + * @return None + ***********************************************************************/ +static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) +{ + volatile uint32_t temp = 0; + + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + + // Get PCLK of I2C controller + if (I2Cx == LPC_I2C0) + { + temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock; + } + else if (I2Cx == LPC_I2C1) + { + temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; + } + else if (I2Cx == LPC_I2C2) + { + temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C2) / target_clock; + } + + /* Set the I2C clock value to register */ + I2Cx->I2SCLH = (uint32_t)(temp / 2); + I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH); +} +/* End of Private Functions --------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup I2C_Public_Functions + * @{ + */ + +/********************************************************************//** + * @brief Initializes the I2Cx peripheral with specified parameter. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] clockrate Target clock rate value to initialized I2C + * peripheral (Hz) + * @return None + *********************************************************************/ +void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate) +{ + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + + if (I2Cx==LPC_I2C0) + { + /* Set up clock and power for I2C0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE); + /* As default, peripheral clock for I2C0 module + * is set to FCCLK / 2 */ + CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2); + } + else if (I2Cx==LPC_I2C1) + { + /* Set up clock and power for I2C1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE); + /* As default, peripheral clock for I2C1 module + * is set to FCCLK / 2 */ + CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2); + } + else if (I2Cx==LPC_I2C2) + { + /* Set up clock and power for I2C2 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE); + /* As default, peripheral clock for I2C2 module + * is set to FCCLK / 2 */ + CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2); + } + else { + // Up-Support this device + return; + } + + /* Set clock rate */ + I2C_SetClock(I2Cx, clockrate); + /* Set I2C operation to default */ + I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); +} + +/*********************************************************************//** + * @brief De-initializes the I2C peripheral registers to their + * default reset values. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_DeInit(LPC_I2C_TypeDef* I2Cx) +{ + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + + /* Disable I2C control */ + I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; + + if (I2Cx==LPC_I2C0) + { + /* Disable power for I2C0 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE); + } + else if (I2Cx==LPC_I2C1) + { + /* Disable power for I2C1 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE); + } + else if (I2Cx==LPC_I2C2) + { + /* Disable power for I2C2 module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE); + } +} + +/*********************************************************************//** + * @brief Enable or disable I2C peripheral's operation + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of I2Cx peripheral's operation + * @return none + **********************************************************************/ +void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + + if (NewState == ENABLE) + { + I2Cx->I2CONSET = I2C_I2CONSET_I2EN; + } + else + { + I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; + } +} + +/*********************************************************************//** + * @brief Enable/Disable interrupt for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of I2C peripheral interrupt in NVIC core + * should be: + * - ENABLE: enable interrupt for this I2C peripheral + * - DISABLE: disable interrupt for this I2C peripheral + * @return None + **********************************************************************/ +void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState) +{ + if (NewState) + { + if(I2Cx == LPC_I2C0) + { + NVIC_EnableIRQ(I2C0_IRQn); + } + else if (I2Cx == LPC_I2C1) + { + NVIC_EnableIRQ(I2C1_IRQn); + } + else if (I2Cx == LPC_I2C2) + { + NVIC_EnableIRQ(I2C2_IRQn); + } + } + else + { + if(I2Cx == LPC_I2C0) + { + NVIC_DisableIRQ(I2C0_IRQn); + } + else if (I2Cx == LPC_I2C1) + { + NVIC_DisableIRQ(I2C1_IRQn); + } + else if (I2Cx == LPC_I2C2) + { + NVIC_DisableIRQ(I2C2_IRQn); + } + } + return; +} + + +/*********************************************************************//** + * @brief General Master Interrupt handler for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx) +{ + int32_t tmp; + uint8_t returnCode; + I2C_M_SETUP_Type *txrx_setup; + + tmp = I2C_getNum(I2Cx); + txrx_setup = (I2C_M_SETUP_Type *) i2cdat[tmp].txrx_setup; + + returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); + // Save current status + txrx_setup->status = returnCode; + // there's no relevant information + if (returnCode == I2C_I2STAT_NO_INF){ + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + return; + } + + /* ----------------------------- TRANSMIT PHASE --------------------------*/ + if (i2cdat[tmp].dir == 0){ + switch (returnCode) + { + /* A start/repeat start condition has been transmitted -------------------*/ + case I2C_I2STAT_M_TX_START: + case I2C_I2STAT_M_TX_RESTART: + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + /* + * If there's any transmit data, then start to + * send SLA+W right now, otherwise check whether if there's + * any receive data for next state. + */ + if ((txrx_setup->tx_data != NULL) && (txrx_setup->tx_length != 0)){ + I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1); + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + } else { + goto next_stage; + } + break; + + /* SLA+W has been transmitted, ACK has been received ----------------------*/ + case I2C_I2STAT_M_TX_SLAW_ACK: + /* Data has been transmitted, ACK has been received */ + case I2C_I2STAT_M_TX_DAT_ACK: + /* Send more data */ + if ((txrx_setup->tx_count < txrx_setup->tx_length) \ + && (txrx_setup->tx_data != NULL)){ + I2Cx->I2DAT = *(uint8_t *)(txrx_setup->tx_data + txrx_setup->tx_count); + txrx_setup->tx_count++; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + } + // no more data, switch to next stage + else { +next_stage: + // change direction + i2cdat[tmp].dir = 1; + // Check if any data to receive + if ((txrx_setup->rx_length != 0) && (txrx_setup->rx_data != NULL)){ + // check whether if we need to issue an repeat start + if ((txrx_setup->tx_length != 0) && (txrx_setup->tx_data != NULL)){ + // Send out an repeat start command + I2Cx->I2CONSET = I2C_I2CONSET_STA; + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; + } + // Don't need issue an repeat start, just goto send SLA+R + else { + goto send_slar; + } + } + // no more data send, the go to end stage now + else { + // success, goto end stage + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto end_stage; + } + } + break; + + /* SLA+W has been transmitted, NACK has been received ----------------------*/ + case I2C_I2STAT_M_TX_SLAW_NACK: + /* Data has been transmitted, NACK has been received -----------------------*/ + case I2C_I2STAT_M_TX_DAT_NACK: + // update status + txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; + goto retry; + /* Arbitration lost in SLA+R/W or Data bytes -------------------------------*/ + case I2C_I2STAT_M_TX_ARB_LOST: + // update status + txrx_setup->status |= I2C_SETUP_STATUS_ARBF; + default: + goto retry; + } + } + + /* ----------------------------- RECEIVE PHASE --------------------------*/ + else if (i2cdat[tmp].dir == 1){ + switch (returnCode){ + /* A start/repeat start condition has been transmitted ---------------------*/ + case I2C_I2STAT_M_RX_START: + case I2C_I2STAT_M_RX_RESTART: + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + /* + * If there's any receive data, then start to + * send SLA+R right now, otherwise check whether if there's + * any receive data for end of state. + */ + if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_length != 0)){ +send_slar: + I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1) | 0x01; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + } else { + // Success, goto end stage + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto end_stage; + } + break; + + /* SLA+R has been transmitted, ACK has been received -----------------*/ + case I2C_I2STAT_M_RX_SLAR_ACK: + if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { + /*Data will be received, ACK will be return*/ + I2Cx->I2CONSET = I2C_I2CONSET_AA; + } + else { + /*Last data will be received, NACK will be return*/ + I2Cx->I2CONCLR = I2C_I2CONSET_AA; + } + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Data has been received, ACK has been returned ----------------------*/ + case I2C_I2STAT_M_RX_DAT_ACK: + // Note save data and increase counter first, then check later + /* Save data */ + if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ + *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); + txrx_setup->rx_count++; + } + if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { + /*Data will be received, ACK will be return*/ + I2Cx->I2CONSET = I2C_I2CONSET_AA; + } + else { + /*Last data will be received, NACK will be return*/ + I2Cx->I2CONCLR = I2C_I2CONSET_AA; + } + + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Data has been received, NACK has been return -------------------------*/ + case I2C_I2STAT_M_RX_DAT_NACK: + /* Save the last data */ + if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ + *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); + txrx_setup->rx_count++; + } + // success, go to end stage + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto end_stage; + + /* SLA+R has been transmitted, NACK has been received ------------------*/ + case I2C_I2STAT_M_RX_SLAR_NACK: + // update status + txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; + goto retry; + + /* Arbitration lost ----------------------------------------------------*/ + case I2C_I2STAT_M_RX_ARB_LOST: + // update status + txrx_setup->status |= I2C_SETUP_STATUS_ARBF; + default: +retry: + // check if retransmission is available + if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max){ + // Clear tx count + txrx_setup->tx_count = 0; + I2Cx->I2CONSET = I2C_I2CONSET_STA; + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; + txrx_setup->retransmissions_count++; + } + // End of stage + else { +end_stage: + // Disable interrupt + I2C_IntCmd(I2Cx, FALSE); + // Send stop + I2C_Stop(I2Cx); + + I2C_MasterComplete[tmp] = TRUE; + } + break; + } + } +} + + +/*********************************************************************//** + * @brief General Slave Interrupt handler for I2C peripheral + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + **********************************************************************/ +void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx) +{ + int32_t tmp; + uint8_t returnCode; + I2C_S_SETUP_Type *txrx_setup; + uint32_t timeout; + + tmp = I2C_getNum(I2Cx); + txrx_setup = (I2C_S_SETUP_Type *) i2cdat[tmp].txrx_setup; + + returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); + // Save current status + txrx_setup->status = returnCode; + // there's no relevant information + if (returnCode == I2C_I2STAT_NO_INF){ + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + return; + } + + + switch (returnCode) + { + + /* No status information */ + case I2C_I2STAT_NO_INF: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Reading phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_SLAW_ACK: + /* General call address has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_GENCALL_ACK: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Previously addressed with own SLA; + * DATA byte has been received; + * ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: + /* DATA has been received, ACK hasn been return */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((txrx_setup->rx_count < txrx_setup->rx_length) \ + && (txrx_setup->rx_data != NULL)){ + *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (uint8_t)I2Cx->I2DAT; + txrx_setup->rx_count++; + } + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Previously addressed with own SLA; + * DATA byte has been received; + * NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: + /* DATA has been received, NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* + * Note that: Return code only let us know a stop condition mixed + * with a repeat start condition in the same code value. + * So we should provide a time-out. In case this is really a stop + * condition, this will return back after time out condition. Otherwise, + * next session that is slave receive data will be completed. + */ + + /* A Stop or a repeat start condition */ + case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: + // Temporally lock the interrupt for timeout condition + I2C_IntCmd(I2Cx, FALSE); + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + // enable time out + timeout = I2C_SLAVE_TIME_OUT; + while(1){ + if (I2Cx->I2CONSET & I2C_I2CONSET_SI){ + // re-Enable interrupt + I2C_IntCmd(I2Cx, TRUE); + break; + } else { + timeout--; + if (timeout == 0){ + // timeout occur, it's really a stop condition + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto s_int_end; + } + } + } + break; + + /* Writing phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_TX_SLAR_ACK: + /* Data has been transmitted, ACK has been received */ + case I2C_I2STAT_S_TX_DAT_ACK: + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((txrx_setup->tx_count < txrx_setup->tx_length) \ + && (txrx_setup->tx_data != NULL)){ + I2Cx->I2DAT = *(uint8_t *) (txrx_setup->tx_data + txrx_setup->tx_count); + txrx_setup->tx_count++; + } + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Data has been transmitted, NACK has been received, + * that means there's no more data to send, exit now */ + /* + * Note: Don't wait for stop event since in slave transmit mode, + * since there no proof lets us know when a stop signal has been received + * on slave side. + */ + case I2C_I2STAT_S_TX_DAT_NACK: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + txrx_setup->status |= I2C_SETUP_STATUS_DONE; + goto s_int_end; + + // Other status must be captured + default: +s_int_end: + // Disable interrupt + I2C_IntCmd(I2Cx, FALSE); + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + I2C_SlaveComplete[tmp] = TRUE; + break; + } +} + +/*********************************************************************//** + * @brief Transmit and Receive data in master mode + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return SUCCESS or ERROR + * + * Note: + * - In case of using I2C to transmit data only, either transmit length set to 0 + * or transmit data pointer set to NULL. + * - In case of using I2C to receive data only, either receive length set to 0 + * or receive data pointer set to NULL. + * - In case of using I2C to transmit followed by receive data, transmit length, + * transmit data pointer, receive length and receive data pointer should be set + * corresponding. + **********************************************************************/ +Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \ + I2C_TRANSFER_OPT_Type Opt) +{ + uint8_t *txdat; + uint8_t *rxdat; + uint32_t CodeStatus; + uint8_t tmp; + + // reset all default state + txdat = (uint8_t *) TransferCfg->tx_data; + rxdat = (uint8_t *) TransferCfg->rx_data; + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + TransferCfg->status = 0; + + if (Opt == I2C_TRANSFER_POLLING){ + + /* First Start condition -------------------------------------------------------------- */ + TransferCfg->retransmissions_count = 0; +retry: + // reset all default state + txdat = (uint8_t *) TransferCfg->tx_data; + rxdat = (uint8_t *) TransferCfg->rx_data; + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + CodeStatus = 0; + + // Start command + CodeStatus = I2C_Start(I2Cx); + if ((CodeStatus != I2C_I2STAT_M_TX_START) \ + && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // save status + TransferCfg->status = CodeStatus; + goto error; + } else { + goto retry; + } + } + + /* In case of sending data first --------------------------------------------------- */ + if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){ + + /* Send slave address + WR direction bit = 0 ----------------------------------- */ + CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); + if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // save status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; + goto error; + } else { + goto retry; + } + } + + /* Send a number of data bytes ---------------------------------------- */ + while (TransferCfg->tx_count < TransferCfg->tx_length) + { + CodeStatus = I2C_SendByte(I2Cx, *txdat); + if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // save status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; + goto error; + } else { + goto retry; + } + } + + txdat++; + TransferCfg->tx_count++; + } + } + + /* Second Start condition (Repeat Start) ------------------------------------------- */ + if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \ + && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ + + CodeStatus = I2C_Start(I2Cx); + if ((CodeStatus != I2C_I2STAT_M_RX_START) \ + && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // Update status + TransferCfg->status = CodeStatus; + goto error; + } else { + goto retry; + } + } + } + + /* Then, start reading after sending data -------------------------------------- */ + if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ + /* Send slave address + RD direction bit = 1 ----------------------------------- */ + + CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); + if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // update status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; + goto error; + } else { + goto retry; + } + } + + /* Receive a number of data bytes ------------------------------------------------- */ + while (TransferCfg->rx_count < TransferCfg->rx_length){ + + /* + * Note that: if data length is only one, the master should not + * issue an ACK signal on bus after reading to avoid of next data frame + * on slave side + */ + if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){ + // Issue an ACK signal for next data frame + CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE); + if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // update status + TransferCfg->status = CodeStatus; + goto error; + } else { + goto retry; + } + } + } else { + // Do not issue an ACK signal + CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE); + if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){ + TransferCfg->retransmissions_count++; + if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ + // update status + TransferCfg->status = CodeStatus; + goto error; + } else { + goto retry; + } + } + } + *rxdat++ = tmp; + TransferCfg->rx_count++; + } + } + + /* Send STOP condition ------------------------------------------------- */ + I2C_Stop(I2Cx); + return SUCCESS; + +error: + // Send stop condition + I2C_Stop(I2Cx); + return ERROR; + } + + else if (Opt == I2C_TRANSFER_INTERRUPT){ + // Setup tx_rx data, callback and interrupt handler + tmp = I2C_getNum(I2Cx); + i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; + // Set direction phase, write first + i2cdat[tmp].dir = 0; + + /* First Start condition -------------------------------------------------------------- */ + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + I2Cx->I2CONSET = I2C_I2CONSET_STA; + I2C_IntCmd(I2Cx, TRUE); + + return (SUCCESS); + } + + return ERROR; +} + +/*********************************************************************//** + * @brief Receive and Transmit data in slave mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that + * contains specified information about the + * configuration for master transfer. + * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for + * interrupt or polling mode. + * @return SUCCESS or ERROR + * + * Note: + * The mode of slave's operation depends on the command sent from master on + * the I2C bus. If the master send a SLA+W command, this sub-routine will + * use receive data length and receive data pointer. If the master send a SLA+R + * command, this sub-routine will use transmit data length and transmit data + * pointer. + * If the master issue an repeat start command or a stop command, the slave will + * enable an time out condition, during time out condition, if there's no activity + * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W), + * the slave then switch to relevant operation mode. The time out should be used + * because the return status code can not show difference from stop and repeat + * start command in slave operation. + * In case of the expected data length from master is greater than data length + * that slave can support: + * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR + * value. + * - In case of writing operation (from master): slave will ignore remain data from master. + **********************************************************************/ +Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \ + I2C_TRANSFER_OPT_Type Opt) +{ + uint8_t *txdat; + uint8_t *rxdat; + volatile uint32_t CodeStatus = 0; + uint32_t timeout; + int32_t time_en; + int32_t tmp; + + // reset all default state + txdat = (uint8_t *) TransferCfg->tx_data; + rxdat = (uint8_t *) TransferCfg->rx_data; + // Reset I2C setup value to default state + TransferCfg->tx_count = 0; + TransferCfg->rx_count = 0; + TransferCfg->status = 0; + + + // Polling option + if (Opt == I2C_TRANSFER_POLLING){ + + /* Set AA bit to ACK command on I2C bus */ + I2Cx->I2CONSET = I2C_I2CONSET_AA; + /* Clear SI bit to be ready ... */ + I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC); + + time_en = 0; + timeout = 0; + + while (1) + { + /* Check SI flag ready */ + if (I2Cx->I2CONSET & I2C_I2CONSET_SI) + { + time_en = 0; + + switch (CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK)) + { + + /* No status information */ + case I2C_I2STAT_NO_INF: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Reading phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_SLAW_ACK: + /* General call address has been received, ACK has been returned */ + case I2C_I2STAT_S_RX_GENCALL_ACK: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Previously addressed with own SLA; + * DATA byte has been received; + * ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: + /* DATA has been received, ACK hasn been return */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((TransferCfg->rx_count < TransferCfg->rx_length) \ + && (TransferCfg->rx_data != NULL)){ + *rxdat++ = (uint8_t)I2Cx->I2DAT; + TransferCfg->rx_count++; + } + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Previously addressed with own SLA; + * DATA byte has been received; + * NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: + /* DATA has been received, NOT ACK has been returned */ + case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* + * Note that: Return code only let us know a stop condition mixed + * with a repeat start condition in the same code value. + * So we should provide a time-out. In case this is really a stop + * condition, this will return back after time out condition. Otherwise, + * next session that is slave receive data will be completed. + */ + + /* A Stop or a repeat start condition */ + case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + // enable time out + time_en = 1; + timeout = 0; + break; + + /* Writing phase -------------------------------------------------------- */ + /* Own SLA+R has been received, ACK has been returned */ + case I2C_I2STAT_S_TX_SLAR_ACK: + /* Data has been transmitted, ACK has been received */ + case I2C_I2STAT_S_TX_DAT_ACK: + /* + * All data bytes that over-flow the specified receive + * data length, just ignore them. + */ + if ((TransferCfg->tx_count < TransferCfg->tx_length) \ + && (TransferCfg->tx_data != NULL)){ + I2Cx->I2DAT = *txdat++; + TransferCfg->tx_count++; + } + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + break; + + /* Data has been transmitted, NACK has been received, + * that means there's no more data to send, exit now */ + /* + * Note: Don't wait for stop event since in slave transmit mode, + * since there no proof lets us know when a stop signal has been received + * on slave side. + */ + case I2C_I2STAT_S_TX_DAT_NACK: + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + // enable time out + time_en = 1; + timeout = 0; + break; + + // Other status must be captured + default: + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + goto s_error; + } + } else if (time_en){ + if (timeout++ > I2C_SLAVE_TIME_OUT){ + // it's really a stop condition, goto end stage + goto s_end_stage; + } + } + } + +s_end_stage: + /* Clear AA bit to disable ACK on I2C bus */ + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; + // Check if there's no error during operation + // Update status + TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE; + return SUCCESS; + +s_error: + /* Clear AA bit to disable ACK on I2C bus */ + I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; + // Update status + TransferCfg->status = CodeStatus; + return ERROR; + } + + else if (Opt == I2C_TRANSFER_INTERRUPT){ + // Setup tx_rx data, callback and interrupt handler + tmp = I2C_getNum(I2Cx); + i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; + // Set direction phase, read first + i2cdat[tmp].dir = 1; + + // Enable AA + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + I2C_IntCmd(I2Cx, TRUE); + + return (SUCCESS); + } + + return ERROR; +} + +/*********************************************************************//** + * @brief Set Own slave address in I2C peripheral corresponding to + * parameter specified in OwnSlaveAddrConfigStruct. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type + * structure that contains the configuration information for the +* specified I2C slave address. + * @return None + **********************************************************************/ +void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) +{ + uint32_t tmp; + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState)); + + tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ + | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; + switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) + { + case 0: + I2Cx->I2ADR0 = tmp; + I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + case 1: + I2Cx->I2ADR1 = tmp; + I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + case 2: + I2Cx->I2ADR2 = tmp; + I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + case 3: + I2Cx->I2ADR3 = tmp; + I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \ + (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); + break; + } +} + + +/*********************************************************************//** + * @brief Configures functionality in I2C monitor mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] MonitorCfgType Monitor Configuration type, should be: + * - I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch' + * the clock line (hold it low) until it has had time to + * respond to an I2C interrupt. + * - I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1' + * and the I2C is in monitor mode, an interrupt will be + * generated on ANY address received. + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return None + **********************************************************************/ +void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + I2Cx->MMCTRL |= MonitorCfgType; + } + else + { + I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Enable/Disable I2C monitor mode + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @param[in] NewState New State of this function, should be: + * - ENABLE: Enable monitor mode. + * - DISABLE: Disable monitor mode. + * @return None + **********************************************************************/ +void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; + I2Cx->I2CONSET = I2C_I2CONSET_AA; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; + } + else + { + I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_AAC; + } + I2C_MonitorBufferIndex = 0; +} + + +/*********************************************************************//** + * @brief Get data from I2C data buffer in monitor mode. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + * Note: In monitor mode, the I2C module may lose the ability to stretch + * the clock (stall the bus) if the ENA_SCL bit is not set. This means that + * the processor will have a limited amount of time to read the contents of + * the data received on the bus. If the processor reads the I2DAT shift + * register, as it ordinarily would, it could have only one bit-time to + * respond to the interrupt before the received data is overwritten by + * new data. + **********************************************************************/ +uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx) +{ + CHECK_PARAM(PARAM_I2Cx(I2Cx)); + return ((uint8_t)(I2Cx->I2DATA_BUFFER)); +} + +/*********************************************************************//** + * @brief Get data from I2C data buffer in monitor mode. + * @param[in] I2Cx I2C peripheral selected, should be + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return None + * Note: In monitor mode, the I2C module may lose the ability to stretch + * the clock (stall the bus) if the ENA_SCL bit is not set. This means that + * the processor will have a limited amount of time to read the contents of + * the data received on the bus. If the processor reads the I2DAT shift + * register, as it ordinarily would, it could have only one bit-time to + * respond to the interrupt before the received data is overwritten by + * new data. + **********************************************************************/ +BOOL_8 I2C_MonitorHandler(LPC_I2C_TypeDef *I2Cx, uint8_t *buffer, uint32_t size) +{ + BOOL_8 ret=FALSE; + + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + + buffer[I2C_MonitorBufferIndex] = (uint8_t)(I2Cx->I2DATA_BUFFER); + I2C_MonitorBufferIndex++; + if(I2C_MonitorBufferIndex >= size) + { + ret = TRUE; + } + return ret; +} +/*********************************************************************//** + * @brief Get status of Master Transfer + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return Master transfer status, could be: + * - TRUE master transfer completed + * - FALSE master transfer have not completed yet + **********************************************************************/ +uint32_t I2C_MasterTransferComplete(LPC_I2C_TypeDef *I2Cx) +{ + uint32_t retval, tmp; + tmp = I2C_getNum(I2Cx); + retval = I2C_MasterComplete[tmp]; + I2C_MasterComplete[tmp] = FALSE; + return retval; +} + +/*********************************************************************//** + * @brief Get status of Slave Transfer + * @param[in] I2Cx I2C peripheral selected, should be: + * - LPC_I2C0 + * - LPC_I2C1 + * - LPC_I2C2 + * @return Complete status, could be: TRUE/FALSE + **********************************************************************/ +uint32_t I2C_SlaveTransferComplete(LPC_I2C_TypeDef *I2Cx) +{ + uint32_t retval, tmp; + tmp = I2C_getNum(I2Cx); + retval = I2C_SlaveComplete[tmp]; + I2C_SlaveComplete[tmp] = FALSE; + return retval; +} + + + +/** + * @} + */ + +#endif /* _I2C */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_i2c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_i2c.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,377 @@ +/***********************************************************************//** + * @file lpc17xx_i2c.h + * @brief Contains all macro definitions and function prototypes + * support for I2C firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup I2C I2C + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_I2C_H_ +#define LPC17XX_I2C_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup I2C_Private_Macros I2C Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*******************************************************************//** + * I2C Control Set register description + *********************************************************************/ +#define I2C_I2CONSET_AA ((0x04)) /*!< Assert acknowledge flag */ +#define I2C_I2CONSET_SI ((0x08)) /*!< I2C interrupt flag */ +#define I2C_I2CONSET_STO ((0x10)) /*!< STOP flag */ +#define I2C_I2CONSET_STA ((0x20)) /*!< START flag */ +#define I2C_I2CONSET_I2EN ((0x40)) /*!< I2C interface enable */ + +/*******************************************************************//** + * I2C Control Clear register description + *********************************************************************/ +/** Assert acknowledge Clear bit */ +#define I2C_I2CONCLR_AAC ((1<<2)) +/** I2C interrupt Clear bit */ +#define I2C_I2CONCLR_SIC ((1<<3)) +/** START flag Clear bit */ +#define I2C_I2CONCLR_STAC ((1<<5)) +/** I2C interface Disable bit */ +#define I2C_I2CONCLR_I2ENC ((1<<6)) + +/********************************************************************//** + * I2C Status Code definition (I2C Status register) + *********************************************************************/ +/* Return Code in I2C status register */ +#define I2C_STAT_CODE_BITMASK ((0xF8)) + +/* I2C return status code definitions ----------------------------- */ + +/** No relevant information */ +#define I2C_I2STAT_NO_INF ((0xF8)) + +/* Master transmit mode -------------------------------------------- */ +/** A start condition has been transmitted */ +#define I2C_I2STAT_M_TX_START ((0x08)) +/** A repeat start condition has been transmitted */ +#define I2C_I2STAT_M_TX_RESTART ((0x10)) +/** SLA+W has been transmitted, ACK has been received */ +#define I2C_I2STAT_M_TX_SLAW_ACK ((0x18)) +/** SLA+W has been transmitted, NACK has been received */ +#define I2C_I2STAT_M_TX_SLAW_NACK ((0x20)) +/** Data has been transmitted, ACK has been received */ +#define I2C_I2STAT_M_TX_DAT_ACK ((0x28)) +/** Data has been transmitted, NACK has been received */ +#define I2C_I2STAT_M_TX_DAT_NACK ((0x30)) +/** Arbitration lost in SLA+R/W or Data bytes */ +#define I2C_I2STAT_M_TX_ARB_LOST ((0x38)) + +/* Master receive mode -------------------------------------------- */ +/** A start condition has been transmitted */ +#define I2C_I2STAT_M_RX_START ((0x08)) +/** A repeat start condition has been transmitted */ +#define I2C_I2STAT_M_RX_RESTART ((0x10)) +/** Arbitration lost */ +#define I2C_I2STAT_M_RX_ARB_LOST ((0x38)) +/** SLA+R has been transmitted, ACK has been received */ +#define I2C_I2STAT_M_RX_SLAR_ACK ((0x40)) +/** SLA+R has been transmitted, NACK has been received */ +#define I2C_I2STAT_M_RX_SLAR_NACK ((0x48)) +/** Data has been received, ACK has been returned */ +#define I2C_I2STAT_M_RX_DAT_ACK ((0x50)) +/** Data has been received, NACK has been return */ +#define I2C_I2STAT_M_RX_DAT_NACK ((0x58)) + +/* Slave receive mode -------------------------------------------- */ +/** Own slave address has been received, ACK has been returned */ +#define I2C_I2STAT_S_RX_SLAW_ACK ((0x60)) + +/** Arbitration lost in SLA+R/W as master */ +#define I2C_I2STAT_S_RX_ARB_LOST_M_SLA ((0x68)) +/** Own SLA+W has been received, ACK returned */ +//#define I2C_I2STAT_S_RX_SLAW_ACK ((0x68)) + +/** General call address has been received, ACK has been returned */ +#define I2C_I2STAT_S_RX_GENCALL_ACK ((0x70)) + +/** Arbitration lost in SLA+R/W (GENERAL CALL) as master */ +#define I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL ((0x78)) +/** General call address has been received, ACK has been returned */ +//#define I2C_I2STAT_S_RX_GENCALL_ACK ((0x78)) + +/** Previously addressed with own SLV address; + * Data has been received, ACK has been return */ +#define I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK ((0x80)) +/** Previously addressed with own SLA; + * Data has been received and NOT ACK has been return */ +#define I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK ((0x88)) +/** Previously addressed with General Call; + * Data has been received and ACK has been return */ +#define I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK ((0x90)) +/** Previously addressed with General Call; + * Data has been received and NOT ACK has been return */ +#define I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK ((0x98)) +/** A STOP condition or repeated START condition has + * been received while still addressed as SLV/REC + * (Slave Receive) or SLV/TRX (Slave Transmit) */ +#define I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX ((0xA0)) + +/** Slave transmit mode */ +/** Own SLA+R has been received, ACK has been returned */ +#define I2C_I2STAT_S_TX_SLAR_ACK ((0xA8)) + +/** Arbitration lost in SLA+R/W as master */ +#define I2C_I2STAT_S_TX_ARB_LOST_M_SLA ((0xB0)) +/** Own SLA+R has been received, ACK has been returned */ +//#define I2C_I2STAT_S_TX_SLAR_ACK ((0xB0)) + +/** Data has been transmitted, ACK has been received */ +#define I2C_I2STAT_S_TX_DAT_ACK ((0xB8)) +/** Data has been transmitted, NACK has been received */ +#define I2C_I2STAT_S_TX_DAT_NACK ((0xC0)) +/** Last data byte in I2DAT has been transmitted (AA = 0); + ACK has been received */ +#define I2C_I2STAT_S_TX_LAST_DAT_ACK ((0xC8)) + +/** Time out in case of using I2C slave mode */ +#define I2C_SLAVE_TIME_OUT 0x10000UL + +/********************************************************************//** + * I2C Data register definition + *********************************************************************/ +/** Mask for I2DAT register*/ +#define I2C_I2DAT_BITMASK ((0xFF)) + +/** Idle data value will be send out in slave mode in case of the actual + * expecting data requested from the master is greater than its sending data + * length that can be supported */ +#define I2C_I2DAT_IDLE_CHAR (0xFF) + +/********************************************************************//** + * I2C Monitor mode control register description + *********************************************************************/ +#define I2C_I2MMCTRL_MM_ENA ((1<<0)) /**< Monitor mode enable */ +#define I2C_I2MMCTRL_ENA_SCL ((1<<1)) /**< SCL output enable */ +#define I2C_I2MMCTRL_MATCH_ALL ((1<<2)) /**< Select interrupt register match */ +#define I2C_I2MMCTRL_BITMASK ((0x07)) /**< Mask for I2MMCTRL register */ + +/********************************************************************//** + * I2C Data buffer register description + *********************************************************************/ +/** I2C Data buffer register bit mask */ +#define I2DATA_BUFFER_BITMASK ((0xFF)) + +/********************************************************************//** + * I2C Slave Address registers definition + *********************************************************************/ +/** General Call enable bit */ +#define I2C_I2ADR_GC ((1<<0)) +/** I2C Slave Address registers bit mask */ +#define I2C_I2ADR_BITMASK ((0xFF)) + +/********************************************************************//** + * I2C Mask Register definition + *********************************************************************/ +/** I2C Mask Register mask field */ +#define I2C_I2MASK_MASK(n) ((n&0xFE)) + +/********************************************************************//** + * I2C SCL HIGH duty cycle Register definition + *********************************************************************/ +/** I2C SCL HIGH duty cycle Register bit mask */ +#define I2C_I2SCLH_BITMASK ((0xFFFF)) + +/********************************************************************//** + * I2C SCL LOW duty cycle Register definition + *********************************************************************/ +/** I2C SCL LOW duty cycle Register bit mask */ +#define I2C_I2SCLL_BITMASK ((0xFFFF)) + +/* I2C status values */ +#define I2C_SETUP_STATUS_ARBF (1<<8) /**< Arbitration false */ +#define I2C_SETUP_STATUS_NOACKF (1<<9) /**< No ACK returned */ +#define I2C_SETUP_STATUS_DONE (1<<10) /**< Status DONE */ + +/*********************************************************************//** + * I2C monitor control configuration defines + **********************************************************************/ +#define I2C_MONITOR_CFG_SCL_OUTPUT I2C_I2MMCTRL_ENA_SCL /**< SCL output enable */ +#define I2C_MONITOR_CFG_MATCHALL I2C_I2MMCTRL_MATCH_ALL /**< Select interrupt register match */ + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/* Macros check I2C slave address */ +#define PARAM_I2C_SLAVEADDR_CH(n) ((n)<=3) + +/** Macro to determine if it is valid SSP port number */ +#define PARAM_I2Cx(n) ((((uint32_t *)n)==((uint32_t *)LPC_I2C0)) \ +|| (((uint32_t *)n)==((uint32_t *)LPC_I2C1)) \ +|| (((uint32_t *)n)==((uint32_t *)LPC_I2C2))) + +/* Macros check I2C monitor configuration type */ +#define PARAM_I2C_MONITOR_CFG(n) ((n==I2C_MONITOR_CFG_SCL_OUTPUT) || (I2C_MONITOR_CFG_MATCHALL)) + +/** + * @} + */ + + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup I2C_Public_Types I2C Public Types + * @{ + */ + +/** + * @brief I2C Own slave address setting structure + */ +typedef struct { + uint8_t SlaveAddrChannel; /**< Slave Address channel in I2C control, + should be in range from 0..3 + */ + uint8_t SlaveAddr_7bit; /**< Value of 7-bit slave address */ + uint8_t GeneralCallState; /**< Enable/Disable General Call Functionality + when I2C control being in Slave mode, should be: + - ENABLE: Enable General Call function. + - DISABLE: Disable General Call function. + */ + uint8_t SlaveAddrMaskValue; /**< Any bit in this 8-bit value (bit 7:1) + which is set to '1' will cause an automatic compare on + the corresponding bit of the received address when it + is compared to the SlaveAddr_7bit value associated with this + mask register. In other words, bits in SlaveAddr_7bit value + which are masked are not taken into account in determining + an address match + */ +} I2C_OWNSLAVEADDR_CFG_Type; + + +/** + * @brief Master transfer setup data structure definitions + */ +typedef struct +{ + uint32_t sl_addr7bit; /**< Slave address in 7bit mode */ + uint8_t* tx_data; /**< Pointer to Transmit data - NULL if data transmit + is not used */ + uint32_t tx_length; /**< Transmit data length - 0 if data transmit + is not used*/ + uint32_t tx_count; /**< Current Transmit data counter */ + uint8_t* rx_data; /**< Pointer to Receive data - NULL if data receive + is not used */ + uint32_t rx_length; /**< Receive data length - 0 if data receive is + not used */ + uint32_t rx_count; /**< Current Receive data counter */ + uint32_t retransmissions_max; /**< Max Re-Transmission value */ + uint32_t retransmissions_count; /**< Current Re-Transmission counter */ + uint32_t status; /**< Current status of I2C activity */ + void (*callback)(void); /**< Pointer to Call back function when transmission complete + used in interrupt transfer mode */ +} I2C_M_SETUP_Type; + + +/** + * @brief Slave transfer setup data structure definitions + */ +typedef struct +{ + uint8_t* tx_data; + uint32_t tx_length; + uint32_t tx_count; + uint8_t* rx_data; + uint32_t rx_length; + uint32_t rx_count; + uint32_t status; + void (*callback)(void); +} I2C_S_SETUP_Type; + +/** + * @brief Transfer option type definitions + */ +typedef enum { + I2C_TRANSFER_POLLING = 0, /**< Transfer in polling mode */ + I2C_TRANSFER_INTERRUPT /**< Transfer in interrupt mode */ +} I2C_TRANSFER_OPT_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup I2C_Public_Functions I2C Public Functions + * @{ + */ + +/* I2C Init/DeInit functions ---------- */ +void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate); +void I2C_DeInit(LPC_I2C_TypeDef* I2Cx); +//void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock); +void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState); + +/* I2C transfer data functions -------- */ +Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, \ + I2C_M_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt); +Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, \ + I2C_S_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt); +uint32_t I2C_MasterTransferComplete(LPC_I2C_TypeDef *I2Cx); +uint32_t I2C_SlaveTransferComplete(LPC_I2C_TypeDef *I2Cx); + + +void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct); +uint8_t I2C_GetLastStatusCode(LPC_I2C_TypeDef* I2Cx); + +/* I2C Monitor functions ---------------*/ +void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState); +void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState); +uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx); +BOOL_8 I2C_MonitorHandler(LPC_I2C_TypeDef *I2Cx, uint8_t *buffer, uint32_t size); + +/* I2C Interrupt handler functions ------*/ +void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState); +void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx); +void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_I2C_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_i2s.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_i2s.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,594 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 i2sMclk; + uint8_t bitrate, channel, wordwidth; + + CHECK_PARAM(PARAM_I2Sx(I2Sx)); + CHECK_PARAM(PRAM_I2S_FREQ(Freq)); + CHECK_PARAM(PARAM_I2S_TRX(TRMode)); + + //set i2s reference is i2s_pclk/2 as default + i2sMclk = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_I2S)/2; + I2Sx->I2STXRATE = 1 | (1<<8); + I2Sx->I2SRXRATE = 1 | (1<<8); + 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); + } + bitrate = i2sMclk/(Freq * channel * wordwidth) - 1; + if (TRMode == I2S_TX_MODE)// Transmitter + { + I2Sx->I2STXBITRATE = bitrate; + } else //Receiver + { + I2Sx->I2SRXBITRATE = bitrate; + } + 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_i2s.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_i2s.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,372 @@ +/***********************************************************************//** + * @file lpc17xx_i2s.h + * @brief Contains all macro definitions and function prototypes + * support for I2S firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup I2S I2S + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_I2S_H_ +#define LPC17XX_I2S_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup I2S_Public_Macros I2S Public Macros + * @{ + */ + +/*********************************************************************//** + * I2S configuration parameter defines + **********************************************************************/ +/** I2S Wordwidth bit */ +#define I2S_WORDWIDTH_8 ((uint32_t)(0)) +#define I2S_WORDWIDTH_16 ((uint32_t)(1)) +#define I2S_WORDWIDTH_32 ((uint32_t)(3)) +/** I2S Channel bit */ +#define I2S_STEREO ((uint32_t)(0)) +#define I2S_MONO ((uint32_t)(1)) +/** I2S Master/Slave mode bit */ +#define I2S_MASTER_MODE ((uint8_t)(0)) +#define I2S_SLAVE_MODE ((uint8_t)(1)) +/** I2S Stop bit */ +#define I2S_STOP_ENABLE ((uint8_t)(1)) +#define I2S_STOP_DISABLE ((uint8_t)(0)) +/** I2S Reset bit */ +#define I2S_RESET_ENABLE ((uint8_t)(1)) +#define I2S_RESET_DISABLE ((uint8_t)(0)) +/** I2S Mute bit */ +#define I2S_MUTE_ENABLE ((uint8_t)(1)) +#define I2S_MUTE_DISABLE ((uint8_t)(0)) +/** I2S Transmit/Receive bit */ +#define I2S_TX_MODE ((uint8_t)(0)) +#define I2S_RX_MODE ((uint8_t)(1)) +/** I2S Clock Select bit */ +#define I2S_CLKSEL_FRDCLK ((uint8_t)(0)) +#define I2S_CLKSEL_MCLK ((uint8_t)(2)) +/** I2S 4-pin Mode bit */ +#define I2S_4PIN_ENABLE ((uint8_t)(1)) +#define I2S_4PIN_DISABLE ((uint8_t)(0)) +/** I2S MCLK Enable bit */ +#define I2S_MCLK_ENABLE ((uint8_t)(1)) +#define I2S_MCLK_DISABLE ((uint8_t)(0)) +/** I2S select DMA bit */ +#define I2S_DMA_1 ((uint8_t)(0)) +#define I2S_DMA_2 ((uint8_t)(1)) + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup I2S_Private_Macros I2S Private Macros + * @{ + */ + +/*********************************************************************//** + * Macro defines for DAO-Digital Audio Output register + **********************************************************************/ +/** I2S wordwide - the number of bytes in data*/ +#define I2S_DAO_WORDWIDTH_8 ((uint32_t)(0)) /** 8 bit */ +#define I2S_DAO_WORDWIDTH_16 ((uint32_t)(1)) /** 16 bit */ +#define I2S_DAO_WORDWIDTH_32 ((uint32_t)(3)) /** 32 bit */ +/** I2S control mono or stereo format */ +#define I2S_DAO_MONO ((uint32_t)(1<<2)) +/** I2S control stop mode */ +#define I2S_DAO_STOP ((uint32_t)(1<<3)) +/** I2S control reset mode */ +#define I2S_DAO_RESET ((uint32_t)(1<<4)) +/** I2S control master/slave mode */ +#define I2S_DAO_SLAVE ((uint32_t)(1<<5)) +/** I2S word select half period minus one */ +#define I2S_DAO_WS_HALFPERIOD(n) ((uint32_t)(n<<6)) +/** I2S control mute mode */ +#define I2S_DAO_MUTE ((uint32_t)(1<<15)) + +/*********************************************************************//** + * Macro defines for DAI-Digital Audio Input register +**********************************************************************/ +/** I2S wordwide - the number of bytes in data*/ +#define I2S_DAI_WORDWIDTH_8 ((uint32_t)(0)) /** 8 bit */ +#define I2S_DAI_WORDWIDTH_16 ((uint32_t)(1)) /** 16 bit */ +#define I2S_DAI_WORDWIDTH_32 ((uint32_t)(3)) /** 32 bit */ +/** I2S control mono or stereo format */ +#define I2S_DAI_MONO ((uint32_t)(1<<2)) +/** I2S control stop mode */ +#define I2S_DAI_STOP ((uint32_t)(1<<3)) +/** I2S control reset mode */ +#define I2S_DAI_RESET ((uint32_t)(1<<4)) +/** I2S control master/slave mode */ +#define I2S_DAI_SLAVE ((uint32_t)(1<<5)) +/** I2S word select half period minus one (9 bits)*/ +#define I2S_DAI_WS_HALFPERIOD(n) ((uint32_t)((n&0x1FF)<<6)) +/** I2S control mute mode */ +#define I2S_DAI_MUTE ((uint32_t)(1<<15)) + +/*********************************************************************//** + * Macro defines for STAT register (Status Feedback register) +**********************************************************************/ +/** I2S Status Receive or Transmit Interrupt */ +#define I2S_STATE_IRQ ((uint32_t)(1)) +/** I2S Status Receive or Transmit DMA1 */ +#define I2S_STATE_DMA1 ((uint32_t)(1<<1)) +/** I2S Status Receive or Transmit DMA2 */ +#define I2S_STATE_DMA2 ((uint32_t)(1<<2)) +/** I2S Status Current level of the Receive FIFO (5 bits)*/ +#define I2S_STATE_RX_LEVEL(n) ((uint32_t)((n&1F)<<8)) +/** I2S Status Current level of the Transmit FIFO (5 bits)*/ +#define I2S_STATE_TX_LEVEL(n) ((uint32_t)((n&1F)<<16)) + +/*********************************************************************//** + * Macro defines for DMA1 register (DMA1 Configuration register) +**********************************************************************/ +/** I2S control DMA1 for I2S receive */ +#define I2S_DMA1_RX_ENABLE ((uint32_t)(1)) +/** I2S control DMA1 for I2S transmit */ +#define I2S_DMA1_TX_ENABLE ((uint32_t)(1<<1)) +/** I2S set FIFO level that trigger a receive DMA request on DMA1 */ +#define I2S_DMA1_RX_DEPTH(n) ((uint32_t)((n&0x1F)<<8)) +/** I2S set FIFO level that trigger a transmit DMA request on DMA1 */ +#define I2S_DMA1_TX_DEPTH(n) ((uint32_t)((n&0x1F)<<16)) + +/*********************************************************************//** + * Macro defines for DMA2 register (DMA2 Configuration register) +**********************************************************************/ +/** I2S control DMA2 for I2S receive */ +#define I2S_DMA2_RX_ENABLE ((uint32_t)(1)) +/** I2S control DMA1 for I2S transmit */ +#define I2S_DMA2_TX_ENABLE ((uint32_t)(1<<1)) +/** I2S set FIFO level that trigger a receive DMA request on DMA1 */ +#define I2S_DMA2_RX_DEPTH(n) ((uint32_t)((n&0x1F)<<8)) +/** I2S set FIFO level that trigger a transmit DMA request on DMA1 */ +#define I2S_DMA2_TX_DEPTH(n) ((uint32_t)((n&0x1F)<<16)) + +/*********************************************************************//** +* Macro defines for IRQ register (Interrupt Request Control register) +**********************************************************************/ +/** I2S control I2S receive interrupt */ +#define I2S_IRQ_RX_ENABLE ((uint32_t)(1)) +/** I2S control I2S transmit interrupt */ +#define I2S_IRQ_TX_ENABLE ((uint32_t)(1<<1)) +/** I2S set the FIFO level on which to create an irq request */ +#define I2S_IRQ_RX_DEPTH(n) ((uint32_t)((n&0x1F)<<8)) +/** I2S set the FIFO level on which to create an irq request */ +#define I2S_IRQ_TX_DEPTH(n) ((uint32_t)((n&0x1F)<<16)) + +/********************************************************************************//** + * Macro defines for TXRATE/RXRATE register (Transmit/Receive Clock Rate register) +*********************************************************************************/ +/** I2S Transmit MCLK rate denominator */ +#define I2S_TXRATE_Y_DIVIDER(n) ((uint32_t)(n&0xFF)) +/** I2S Transmit MCLK rate denominator */ +#define I2S_TXRATE_X_DIVIDER(n) ((uint32_t)((n&0xFF)<<8)) +/** I2S Receive MCLK rate denominator */ +#define I2S_RXRATE_Y_DIVIDER(n) ((uint32_t)(n&0xFF)) +/** I2S Receive MCLK rate denominator */ +#define I2S_RXRATE_X_DIVIDER(n) ((uint32_t)((n&0xFF)<<8)) + +/*************************************************************************************//** + * Macro defines for TXBITRATE & RXBITRATE register (Transmit/Receive Bit Rate register) +**************************************************************************************/ +#define I2S_TXBITRATE(n) ((uint32_t)(n&0x3F)) +#define I2S_RXBITRATE(n) ((uint32_t)(n&0x3F)) + +/**********************************************************************************//** + * Macro defines for TXMODE/RXMODE register (Transmit/Receive Mode Control register) +************************************************************************************/ +/** I2S Transmit select clock source (2 bits)*/ +#define I2S_TXMODE_CLKSEL(n) ((uint32_t)(n&0x03)) +/** I2S Transmit control 4-pin mode */ +#define I2S_TXMODE_4PIN_ENABLE ((uint32_t)(1<<2)) +/** I2S Transmit control the TX_MCLK output */ +#define I2S_TXMODE_MCENA ((uint32_t)(1<<3)) +/** I2S Receive select clock source */ +#define I2S_RXMODE_CLKSEL(n) ((uint32_t)(n&0x03)) +/** I2S Receive control 4-pin mode */ +#define I2S_RXMODE_4PIN_ENABLE ((uint32_t)(1<<2)) +/** I2S Receive control the TX_MCLK output */ +#define I2S_RXMODE_MCENA ((uint32_t)(1<<3)) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid I2S peripheral */ +#define PARAM_I2Sx(n) (((uint32_t *)n)==((uint32_t *)LPC_I2S)) +/** Macro to check Data to send valid */ +#define PRAM_I2S_FREQ(freq) ((freq>=16000)&&(freq <= 96000)) +/* Macro check I2S word width type */ +#define PARAM_I2S_WORDWIDTH(n) ((n==I2S_WORDWIDTH_8)||(n==I2S_WORDWIDTH_16)\ +||(n==I2S_WORDWIDTH_32)) +/* Macro check I2S channel type */ +#define PARAM_I2S_CHANNEL(n) ((n==I2S_STEREO)||(n==I2S_MONO)) +/* Macro check I2S master/slave mode */ +#define PARAM_I2S_WS_SEL(n) ((n==I2S_MASTER_MODE)||(n==I2S_SLAVE_MODE)) +/* Macro check I2S stop mode */ +#define PARAM_I2S_STOP(n) ((n==I2S_STOP_ENABLE)||(n==I2S_STOP_DISABLE)) +/* Macro check I2S reset mode */ +#define PARAM_I2S_RESET(n) ((n==I2S_RESET_ENABLE)||(n==I2S_RESET_DISABLE)) +/* Macro check I2S reset mode */ +#define PARAM_I2S_MUTE(n) ((n==I2S_MUTE_ENABLE)||(n==I2S_MUTE_DISABLE)) +/* Macro check I2S transmit/receive mode */ +#define PARAM_I2S_TRX(n) ((n==I2S_TX_MODE)||(n==I2S_RX_MODE)) +/* Macro check I2S clock select mode */ +#define PARAM_I2S_CLKSEL(n) ((n==I2S_CLKSEL_FRDCLK)||(n==I2S_CLKSEL_MCLK)) +/* Macro check I2S 4-pin mode */ +#define PARAM_I2S_4PIN(n) ((n==I2S_4PIN_ENABLE)||(n==I2S_4PIN_DISABLE)) +/* Macro check I2S MCLK mode */ +#define PARAM_I2S_MCLK(n) ((n==I2S_MCLK_ENABLE)||(n==I2S_MCLK_DISABLE)) +/* Macro check I2S DMA mode */ +#define PARAM_I2S_DMA(n) ((n==I2S_DMA_1)||(n==I2S_DMA_2)) +/* Macro check I2S DMA depth value */ +#define PARAM_I2S_DMA_DEPTH(n) ((n)<=31) +/* Macro check I2S irq level value */ +#define PARAM_I2S_IRQ_LEVEL(n) ((n)<=31) +/* Macro check I2S half-period value */ +#define PARAM_I2S_HALFPERIOD(n) ((n>0)&&(n<512)) +/* Macro check I2S bit-rate value */ +#define PARAM_I2S_BITRATE(n) ((n)<=63) +/** + * @} + */ + + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup I2S_Public_Types I2S Public Types + * @{ + */ + +/** + * @brief I2S configuration structure definition + */ +typedef struct { + uint8_t wordwidth; /** the number of bytes in data as follow: + -I2S_WORDWIDTH_8: 8 bit data + -I2S_WORDWIDTH_16: 16 bit data + -I2S_WORDWIDTH_32: 32 bit data */ + uint8_t mono; /** Set mono/stereo mode, should be: + - I2S_STEREO: stereo mode + - I2S_MONO: mono mode */ + uint8_t stop; /** Disables accesses on FIFOs, should be: + - I2S_STOP_ENABLE: enable stop mode + - I2S_STOP_DISABLE: disable stop mode */ + uint8_t reset; /** Asynchronously reset tje transmit channel and FIFO, should be: + - I2S_RESET_ENABLE: enable reset mode + - I2S_RESET_DISABLE: disable reset mode */ + uint8_t ws_sel; /** Set Master/Slave mode, should be: + - I2S_MASTER_MODE: I2S master mode + - I2S_SLAVE_MODE: I2S slave mode */ + uint8_t mute; /** MUTE mode: when true, the transmit channel sends only zeroes, shoule be: + - I2S_MUTE_ENABLE: enable mute mode + - I2S_MUTE_DISABLE: disable mute mode */ + uint8_t Reserved0[2]; +} I2S_CFG_Type; + +/** + * @brief I2S DMA configuration structure definition + */ +typedef struct { + uint8_t DMAIndex; /** Select DMA1 or DMA2, should be: + - I2S_DMA_1: DMA1 + - I2S_DMA_2: DMA2 */ + uint8_t depth; /** FIFO level that triggers a DMA request */ + uint8_t Reserved0[2]; +}I2S_DMAConf_Type; + +/** + * @brief I2S mode configuration structure definition + */ +typedef struct{ + uint8_t clksel; /** Clock source selection, should be: + - I2S_CLKSEL_FRDCLK: Select the fractional rate divider clock output + - I2S_CLKSEL_MCLK: Select the MCLK signal as the clock source */ + uint8_t fpin; /** Select four pin mode, should be: + - I2S_4PIN_ENABLE: 4-pin enable + - I2S_4PIN_DISABLE: 4-pin disable */ + uint8_t mcena; /** Select MCLK mode, should be: + - I2S_MCLK_ENABLE: MCLK enable for output + - I2S_MCLK_DISABLE: MCLK disable for output */ + uint8_t Reserved; +}I2S_MODEConf_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup I2S_Public_Functions I2S Public Functions + * @{ + */ +/* I2S Init/DeInit functions ---------*/ +void I2S_Init(LPC_I2S_TypeDef *I2Sx); +void I2S_DeInit(LPC_I2S_TypeDef *I2Sx); + +/* I2S configuration functions --------*/ +void I2S_Config(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct); +Status I2S_FreqConfig(LPC_I2S_TypeDef *I2Sx, uint32_t Freq, uint8_t TRMode); +void I2S_SetBitRate(LPC_I2S_TypeDef *I2Sx, uint8_t bitrate, uint8_t TRMode); +void I2S_ModeConfig(LPC_I2S_TypeDef *I2Sx, I2S_MODEConf_Type* ModeConfig, uint8_t TRMode); +uint8_t I2S_GetLevel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); + +/* I2S operate functions -------------*/ +void I2S_Send(LPC_I2S_TypeDef *I2Sx, uint32_t BufferData); +uint32_t I2S_Receive(LPC_I2S_TypeDef* I2Sx); +void I2S_Start(LPC_I2S_TypeDef *I2Sx); +void I2S_Pause(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); +void I2S_Mute(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); +void I2S_Stop(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode); + +/* I2S DMA functions ----------------*/ +void I2S_DMAConfig(LPC_I2S_TypeDef *I2Sx, I2S_DMAConf_Type* DMAConfig, uint8_t TRMode); +void I2S_DMACmd(LPC_I2S_TypeDef *I2Sx, uint8_t DMAIndex,uint8_t TRMode, FunctionalState NewState); + +/* I2S IRQ functions ----------------*/ +void I2S_IRQCmd(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode, FunctionalState NewState); +void I2S_IRQConfig(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, uint8_t level); +FunctionalState I2S_GetIRQStatus(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode); +uint8_t I2S_GetIRQDepth(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC17XX_SSP_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_libcfg_default.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_libcfg_default.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,64 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * 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. + **************************************************************************/ + +/* 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_libcfg_default.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_libcfg_default.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,170 @@ +/***********************************************************************//** + * @file lpc17xx_libcfg_default.h + * @brief Default Library configuration header file + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * 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. + **************************************************************************/ + +/* Library Configuration group ----------------------------------------------------------- */ +/** @defgroup LIBCFG_DEFAULT LIBCFG_DEFAULT + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_LIBCFG_DEFAULT_H_ +#define LPC17XX_LIBCFG_DEFAULT_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc_types.h" + + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup LIBCFG_DEFAULT_Public_Macros LIBCFG_DEFAULT Public Macros + * @{ + */ + +/************************** DEBUG MODE DEFINITIONS *********************************/ +/* Un-comment the line below to compile the library in DEBUG mode, this will expanse + the "CHECK_PARAM" macro in the FW library code */ + +#define DEBUG + + +/******************* PERIPHERAL FW LIBRARY CONFIGURATION DEFINITIONS ***********************/ +/* Comment the line below to disable the specific peripheral inclusion */ + +/* DEBUG_FRAMWORK ------------------------------ */ +#define _DBGFWK + +/* GPIO ------------------------------- */ +#define _GPIO + +/* EXTI ------------------------------- */ +#define _EXTI + +/* UART ------------------------------- */ +#define _UART +#define _UART0 +#define _UART1 +#define _UART2 +#define _UART3 + +/* SPI ------------------------------- */ +#define _SPI + +/* SYSTICK --------------------------- */ +#define _SYSTICK + +/* SSP ------------------------------- */ +#define _SSP +#define _SSP0 +#define _SSP1 + + +/* I2C ------------------------------- */ +#define _I2C +#define _I2C0 +#define _I2C1 +#define _I2C2 + +/* TIMER ------------------------------- */ +#define _TIM + +/* WDT ------------------------------- */ +#define _WDT + + +/* GPDMA ------------------------------- */ +#define _GPDMA + + +/* DAC ------------------------------- */ +#define _DAC + +/* DAC ------------------------------- */ +#define _ADC + + +/* PWM ------------------------------- */ +#define _PWM +#define _PWM1 + +/* RTC ------------------------------- */ +#define _RTC + +/* I2S ------------------------------- */ +#define _I2S + +/* USB device ------------------------------- */ +#define _USBDEV +#define _USB_DMA + +/* QEI ------------------------------- */ +#define _QEI + +/* MCPWM ------------------------------- */ +#define _MCPWM + +/* CAN--------------------------------*/ +#define _CAN + +/* RIT ------------------------------- */ +#define _RIT + +/* EMAC ------------------------------ */ +#define _EMAC + +/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/ + +#ifdef DEBUG +/******************************************************************************* +* @brief The CHECK_PARAM macro is used for function's parameters check. +* It is used only if the library is compiled in DEBUG mode. +* @param[in] expr - If expr is false, it calls check_failed() function +* which reports the name of the source file and the source +* line number of the call that failed. +* - If expr is true, it returns no value. +* @return None +*******************************************************************************/ +#define CHECK_PARAM(expr) (((expr) != 0) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__)) +#else +#define CHECK_PARAM(expr) +#endif /* DEBUG */ + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup LIBCFG_DEFAULT_Public_Functions LIBCFG_DEFAULT Public Functions + * @{ + */ + +#ifdef DEBUG +void check_failed(uint8_t *file, uint32_t line); +#endif + +/** + * @} + */ + +#endif /* LPC17XX_LIBCFG_DEFAULT_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_mcpwm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_mcpwm.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,497 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_mcpwm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_mcpwm.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,317 @@ +/***********************************************************************//** + * @file lpc17xx_mcpwm.h + * @brief Contains all macro definitions and function prototypes + * support for Motor Control PWM firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup MCPWM MCPWM + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_MCPWM_H_ +#define LPC17XX_MCPWM_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup MCPWM_Public_Macros MCPWM Public Macros + * @{ + */ + + +/** Edge aligned mode for channel in MCPWM */ +#define MCPWM_CHANNEL_EDGE_MODE ((uint32_t)(0)) +/** Center aligned mode for channel in MCPWM */ +#define MCPWM_CHANNEL_CENTER_MODE ((uint32_t)(1)) + +/** Polarity of the MCOA and MCOB pins: Passive state is LOW, active state is HIGH */ +#define MCPWM_CHANNEL_PASSIVE_LO ((uint32_t)(0)) +/** Polarity of the MCOA and MCOB pins: Passive state is HIGH, active state is LOW */ +#define MCPWM_CHANNEL_PASSIVE_HI ((uint32_t)(1)) + +/* Output Patent in 3-phase DC mode, the internal MCOA0 signal is routed to any or all of + * the six output pins under the control of the bits in this register */ +#define MCPWM_PATENT_A0 ((uint32_t)(1<<0)) /**< MCOA0 tracks internal MCOA0 */ +#define MCPWM_PATENT_B0 ((uint32_t)(1<<1)) /**< MCOB0 tracks internal MCOA0 */ +#define MCPWM_PATENT_A1 ((uint32_t)(1<<2)) /**< MCOA1 tracks internal MCOA0 */ +#define MCPWM_PATENT_B1 ((uint32_t)(1<<3)) /**< MCOB1 tracks internal MCOA0 */ +#define MCPWM_PATENT_A2 ((uint32_t)(1<<4)) /**< MCOA2 tracks internal MCOA0 */ +#define MCPWM_PATENT_B2 ((uint32_t)(1<<5)) /**< MCOB2 tracks internal MCOA0 */ + +/* Interrupt type in MCPWM */ +/** Limit interrupt for channel (0) */ +#define MCPWM_INTFLAG_LIM0 MCPWM_INT_ILIM(0) +/** Match interrupt for channel (0) */ +#define MCPWM_INTFLAG_MAT0 MCPWM_INT_IMAT(0) +/** Capture interrupt for channel (0) */ +#define MCPWM_INTFLAG_CAP0 MCPWM_INT_ICAP(0) + +/** Limit interrupt for channel (1) */ +#define MCPWM_INTFLAG_LIM1 MCPWM_INT_ILIM(1) +/** Match interrupt for channel (1) */ +#define MCPWM_INTFLAG_MAT1 MCPWM_INT_IMAT(1) +/** Capture interrupt for channel (1) */ +#define MCPWM_INTFLAG_CAP1 MCPWM_INT_ICAP(1) + +/** Limit interrupt for channel (2) */ +#define MCPWM_INTFLAG_LIM2 MCPWM_INT_ILIM(2) +/** Match interrupt for channel (2) */ +#define MCPWM_INTFLAG_MAT2 MCPWM_INT_IMAT(2) +/** Capture interrupt for channel (2) */ +#define MCPWM_INTFLAG_CAP2 MCPWM_INT_ICAP(2) + +/** Fast abort interrupt */ +#define MCPWM_INTFLAG_ABORT MCPWM_INT_ABORT + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup MCPWM_Private_Macros MCPWM Private Macros + * @{ + */ + +/*********************************************************************//** + * Macro defines for MCPWM Control register + **********************************************************************/ +/* MCPWM Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Control read address + * - MCPWM Control set address + * - MCPWM Control clear address + */ +#define MCPWM_CON_RUN(n) (((n>=0)&&(n<=2)) ? ((uint32_t)(1<<((n*8)+0))) : (0)) /**< Stops/starts timer channel n */ +#define MCPWM_CON_CENTER(n) (((n)<=2) ? ((uint32_t)(1<<((n*8)+1))) : (0)) /**< Edge/center aligned operation for channel n */ +#define MCPWM_CON_POLAR(n) (((n)<=2) ? ((uint32_t)(1<<((n*8)+2))) : (0)) /**< Select polarity of the MCOAn and MCOBn pin */ +#define MCPWM_CON_DTE(n) (((n)<=2) ? ((uint32_t)(1<<((n*8)+3))) : (0)) /**< Control the dead-time feature for channel n */ +#define MCPWM_CON_DISUP(n) (((n)<=2) ? ((uint32_t)(1<<((n*8)+4))) : (0)) /**< Enable/Disable update of functional register for channel n */ +#define MCPWM_CON_INVBDC ((uint32_t)(1<<29)) /**< Control the polarity for all 3 channels */ +#define MCPWM_CON_ACMODE ((uint32_t)(1<<30)) /**< 3-phase AC mode select */ +#define MCPWM_CON_DCMODE ((uint32_t)(1UL<<31)) /**< 3-phase DC mode select */ + +/*********************************************************************//** + * Macro defines for MCPWM Capture Control register + **********************************************************************/ +/* Capture Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Capture Control read address + * - MCPWM Capture Control set address + * - MCPWM Capture control clear address + */ +/** Enables/Disable channel (cap) capture event on a rising edge on MCI(mci) */ +#define MCPWM_CAPCON_CAPMCI_RE(cap,mci) ((((cap)<=2)&&((mci)<=2)) ? ((uint32_t)(1<<((cap*6)+(mci*2)+0))) : (0)) +/** Enables/Disable channel (cap) capture event on a falling edge on MCI(mci) */ +#define MCPWM_CAPCON_CAPMCI_FE(cap,mci) ((((cap)<=2)&&((mci)<=2)) ? ((uint32_t)(1<<((cap*6)+(mci*2)+1))) : (0)) +/** TC(n) is reset by channel (n) capture event */ +#define MCPWM_CAPCON_RT(n) (((n)<=2) ? ((uint32_t)(1<<(18+(n)))) : (0)) +/** Hardware noise filter: channel (n) capture events are delayed */ +#define MCPWM_CAPCON_HNFCAP(n) (((n)<=2) ? ((uint32_t)(1<<(21+(n)))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Interrupt register + **********************************************************************/ +/* Interrupt registers, these macro definitions below can be applied for these + * register type: + * - MCPWM Interrupt Enable read address + * - MCPWM Interrupt Enable set address + * - MCPWM Interrupt Enable clear address + * - MCPWM Interrupt Flags read address + * - MCPWM Interrupt Flags set address + * - MCPWM Interrupt Flags clear address + */ +/** Limit interrupt for channel (n) */ +#define MCPWM_INT_ILIM(n) (((n>=0)&&(n<=2)) ? ((uint32_t)(1<<((n*4)+0))) : (0)) +/** Match interrupt for channel (n) */ +#define MCPWM_INT_IMAT(n) (((n>=0)&&(n<=2)) ? ((uint32_t)(1<<((n*4)+1))) : (0)) +/** Capture interrupt for channel (n) */ +#define MCPWM_INT_ICAP(n) (((n>=0)&&(n<=2)) ? ((uint32_t)(1<<((n*4)+2))) : (0)) +/** Fast abort interrupt */ +#define MCPWM_INT_ABORT ((uint32_t)(1<<15)) + +/*********************************************************************//** + * Macro defines for MCPWM Count Control register + **********************************************************************/ +/* MCPWM Count Control register, these macro definitions below can be applied for these + * register type: + * - MCPWM Count Control read address + * - MCPWM Count Control set address + * - MCPWM Count Control clear address + */ +/** Counter(tc) advances on a rising edge on MCI(mci) pin */ +#define MCPWM_CNTCON_TCMCI_RE(tc,mci) ((((tc)<=2)&&((mci)<=2)) ? ((uint32_t)(1<<((6*tc)+(2*mci)+0))) : (0)) +/** Counter(cnt) advances on a falling edge on MCI(mci) pin */ +#define MCPWM_CNTCON_TCMCI_FE(tc,mci) ((((tc)<=2)&&((mci)<=2)) ? ((uint32_t)(1<<((6*tc)+(2*mci)+1))) : (0)) +/** Channel (n) is in counter mode */ +#define MCPWM_CNTCON_CNTR(n) (((n)<=2) ? ((uint32_t)(1<<(29+n))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Dead-time register + **********************************************************************/ +/** Dead time value x for channel n */ +#define MCPWM_DT(n,x) (((n)<=2) ? ((uint32_t)((x&0x3FF)<<(n*10))) : (0)) + +/*********************************************************************//** + * Macro defines for MCPWM Communication Pattern register + **********************************************************************/ +#define MCPWM_CP_A0 ((uint32_t)(1<<0)) /**< MCOA0 tracks internal MCOA0 */ +#define MCPWM_CP_B0 ((uint32_t)(1<<1)) /**< MCOB0 tracks internal MCOA0 */ +#define MCPWM_CP_A1 ((uint32_t)(1<<2)) /**< MCOA1 tracks internal MCOA0 */ +#define MCPWM_CP_B1 ((uint32_t)(1<<3)) /**< MCOB1 tracks internal MCOA0 */ +#define MCPWM_CP_A2 ((uint32_t)(1<<4)) /**< MCOA2 tracks internal MCOA0 */ +#define MCPWM_CP_B2 ((uint32_t)(1<<5)) /**< MCOB2 tracks internal MCOA0 */ + +/*********************************************************************//** + * Macro defines for MCPWM Capture clear address register + **********************************************************************/ +/** Clear the MCCAP (n) register */ +#define MCPWM_CAPCLR_CAP(n) (((n)<=2) ? ((uint32_t)(1<<n)) : (0)) + + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup MCPWM_Public_Types MCPWM Public Types + * @{ + */ + +/** + * @brief Motor Control PWM Channel Configuration structure type definition + */ +typedef struct { + uint32_t channelType; /**< Edge/center aligned mode for this channel, + should be: + - MCPWM_CHANNEL_EDGE_MODE: Channel is in Edge mode + - MCPWM_CHANNEL_CENTER_MODE: Channel is in Center mode + */ + uint32_t channelPolarity; /**< Polarity of the MCOA and MCOB pins, should be: + - MCPWM_CHANNEL_PASSIVE_LO: Passive state is LOW, active state is HIGH + - MCPWM_CHANNEL_PASSIVE_HI: Passive state is HIGH, active state is LOW + */ + uint32_t channelDeadtimeEnable; /**< Enable/Disable DeadTime function for channel, should be: + - ENABLE. + - DISABLE. + */ + uint32_t channelDeadtimeValue; /**< DeadTime value, should be less than 0x3FF */ + uint32_t channelUpdateEnable; /**< Enable/Disable updates of functional registers, + should be: + - ENABLE. + - DISABLE. + */ + uint32_t channelTimercounterValue; /**< MCPWM Timer Counter value */ + uint32_t channelPeriodValue; /**< MCPWM Period value */ + uint32_t channelPulsewidthValue; /**< MCPWM Pulse Width value */ +} MCPWM_CHANNEL_CFG_Type; + +/** + * @brief MCPWM Capture Configuration type definition + */ +typedef struct { + uint32_t captureChannel; /**< Capture Channel Number, should be in range from 0 to 2 */ + uint32_t captureRising; /**< Enable/Disable Capture on Rising Edge event, should be: + - ENABLE. + - DISABLE. + */ + uint32_t captureFalling; /**< Enable/Disable Capture on Falling Edge event, should be: + - ENABLE. + - DISABLE. + */ + uint32_t timerReset; /**< Enable/Disable Timer reset function an capture, should be: + - ENABLE. + - DISABLE. + */ + uint32_t hnfEnable; /**< Enable/Disable Hardware noise filter function, should be: + - ENABLE. + - DISABLE. + */ +} MCPWM_CAPTURE_CFG_Type; + + +/** + * @brief MCPWM Count Control Configuration type definition + */ +typedef struct { + uint32_t counterChannel; /**< Counter Channel Number, should be in range from 0 to 2 */ + uint32_t countRising; /**< Enable/Disable Capture on Rising Edge event, should be: + - ENABLE. + - DISABLE. + */ + uint32_t countFalling; /**< Enable/Disable Capture on Falling Edge event, should be: + - ENABLE. + - DISABLE. + */ +} MCPWM_COUNT_CFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup MCPWM_Public_Functions MCPWM Public Functions + * @{ + */ + +void MCPWM_Init(LPC_MCPWM_TypeDef *MCPWMx); +void MCPWM_ConfigChannel(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CHANNEL_CFG_Type * channelSetup); +void MCPWM_WriteToShadow(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CHANNEL_CFG_Type *channelSetup); +void MCPWM_ConfigCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + MCPWM_CAPTURE_CFG_Type *captureConfig); +void MCPWM_ClearCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel); +uint32_t MCPWM_GetCapture(LPC_MCPWM_TypeDef *MCPWMx, uint32_t captureChannel); +void MCPWM_CountConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t channelNum, + uint32_t countMode, MCPWM_COUNT_CFG_Type *countConfig); +void MCPWM_Start(LPC_MCPWM_TypeDef *MCPWMx,uint32_t channel0, uint32_t channel1, uint32_t channel2); +void MCPWM_Stop(LPC_MCPWM_TypeDef *MCPWMx,uint32_t channel0, uint32_t channel1, uint32_t channel2); +void MCPWM_ACMode(LPC_MCPWM_TypeDef *MCPWMx,uint32_t acMode); +void MCPWM_DCMode(LPC_MCPWM_TypeDef *MCPWMx, uint32_t dcMode, + uint32_t outputInvered, uint32_t outputPattern); +void MCPWM_IntConfig(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType, FunctionalState NewState); +void MCPWM_IntSet(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType); +void MCPWM_IntClear(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType); +FlagStatus MCPWM_GetIntStatus(LPC_MCPWM_TypeDef *MCPWMx, uint32_t ulIntType); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_MCPWM_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_nvic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_nvic.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,136 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_nvic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_nvic.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,64 @@ +/***********************************************************************//** + * @file lpc17xx_nvic.h + * @brief Contains all macro definitions and function prototypes + * support for Nesting Vectored Interrupt firmware library + * on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup NVIC NVIC + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_NVIC_H_ +#define LPC17XX_NVIC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup NVIC_Public_Functions NVIC Public Functions + * @{ + */ + +void NVIC_DeInit(void); +void NVIC_SCBDeInit(void); +void NVIC_SetVTOR(uint32_t offset); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_NVIC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_pinsel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_pinsel.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,307 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = 0; + + 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_pinsel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_pinsel.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,191 @@ +/***********************************************************************//** + * @file lpc17xx_pinsel.h + * @brief Contains all macro definitions and function prototypes + * support for Pin connect block firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup PINSEL PINSEL + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_PINSEL_H_ +#define LPC17XX_PINSEL_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Macros PINSEL Public Macros + * @{ + */ + +/*********************************************************************//** + *!< Macros define for PORT Selection + ***********************************************************************/ +#define PINSEL_PORT_0 ((0)) /**< PORT 0*/ +#define PINSEL_PORT_1 ((1)) /**< PORT 1*/ +#define PINSEL_PORT_2 ((2)) /**< PORT 2*/ +#define PINSEL_PORT_3 ((3)) /**< PORT 3*/ +#define PINSEL_PORT_4 ((4)) /**< PORT 4*/ + +/*********************************************************************** + * Macros define for Pin Function selection + **********************************************************************/ +#define PINSEL_FUNC_0 ((0)) /**< default function*/ +#define PINSEL_FUNC_1 ((1)) /**< first alternate function*/ +#define PINSEL_FUNC_2 ((2)) /**< second alternate function*/ +#define PINSEL_FUNC_3 ((3)) /**< third or reserved alternate function*/ + +/*********************************************************************** + * Macros define for Pin Number of Port + **********************************************************************/ +#define PINSEL_PIN_0 ((0)) /**< Pin 0 */ +#define PINSEL_PIN_1 ((1)) /**< Pin 1 */ +#define PINSEL_PIN_2 ((2)) /**< Pin 2 */ +#define PINSEL_PIN_3 ((3)) /**< Pin 3 */ +#define PINSEL_PIN_4 ((4)) /**< Pin 4 */ +#define PINSEL_PIN_5 ((5)) /**< Pin 5 */ +#define PINSEL_PIN_6 ((6)) /**< Pin 6 */ +#define PINSEL_PIN_7 ((7)) /**< Pin 7 */ +#define PINSEL_PIN_8 ((8)) /**< Pin 8 */ +#define PINSEL_PIN_9 ((9)) /**< Pin 9 */ +#define PINSEL_PIN_10 ((10)) /**< Pin 10 */ +#define PINSEL_PIN_11 ((11)) /**< Pin 11 */ +#define PINSEL_PIN_12 ((12)) /**< Pin 12 */ +#define PINSEL_PIN_13 ((13)) /**< Pin 13 */ +#define PINSEL_PIN_14 ((14)) /**< Pin 14 */ +#define PINSEL_PIN_15 ((15)) /**< Pin 15 */ +#define PINSEL_PIN_16 ((16)) /**< Pin 16 */ +#define PINSEL_PIN_17 ((17)) /**< Pin 17 */ +#define PINSEL_PIN_18 ((18)) /**< Pin 18 */ +#define PINSEL_PIN_19 ((19)) /**< Pin 19 */ +#define PINSEL_PIN_20 ((20)) /**< Pin 20 */ +#define PINSEL_PIN_21 ((21)) /**< Pin 21 */ +#define PINSEL_PIN_22 ((22)) /**< Pin 22 */ +#define PINSEL_PIN_23 ((23)) /**< Pin 23 */ +#define PINSEL_PIN_24 ((24)) /**< Pin 24 */ +#define PINSEL_PIN_25 ((25)) /**< Pin 25 */ +#define PINSEL_PIN_26 ((26)) /**< Pin 26 */ +#define PINSEL_PIN_27 ((27)) /**< Pin 27 */ +#define PINSEL_PIN_28 ((28)) /**< Pin 28 */ +#define PINSEL_PIN_29 ((29)) /**< Pin 29 */ +#define PINSEL_PIN_30 ((30)) /**< Pin 30 */ +#define PINSEL_PIN_31 ((31)) /**< Pin 31 */ + +/*********************************************************************** + * Macros define for Pin mode + **********************************************************************/ +#define PINSEL_PINMODE_PULLUP ((0)) /**< Internal pull-up resistor*/ +#define PINSEL_PINMODE_TRISTATE ((2)) /**< Tri-state */ +#define PINSEL_PINMODE_PULLDOWN ((3)) /**< Internal pull-down resistor */ + +/*********************************************************************** + * Macros define for Pin mode (normal/open drain) + **********************************************************************/ +#define PINSEL_PINMODE_NORMAL ((0)) /**< Pin is in the normal (not open drain) mode.*/ +#define PINSEL_PINMODE_OPENDRAIN ((1)) /**< Pin is in the open drain mode */ + +/*********************************************************************** + * Macros define for I2C mode + ***********************************************************************/ +#define PINSEL_I2C_Normal_Mode ((0)) /**< The standard drive mode */ +#define PINSEL_I2C_Fast_Mode ((1)) /**< Fast Mode Plus drive mode */ + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup PINSEL_Private_Macros PINSEL Private Macros + * @{ + */ + +/* Pin selection define */ +/* I2C Pin Configuration register bit description */ +#define PINSEL_I2CPADCFG_SDADRV0 _BIT(0) /**< Drive mode control for the SDA0 pin, P0.27 */ +#define PINSEL_I2CPADCFG_SDAI2C0 _BIT(1) /**< I2C mode control for the SDA0 pin, P0.27 */ +#define PINSEL_I2CPADCFG_SCLDRV0 _BIT(2) /**< Drive mode control for the SCL0 pin, P0.28 */ +#define PINSEL_I2CPADCFG_SCLI2C0 _BIT(3) /**< I2C mode control for the SCL0 pin, P0.28 */ + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Types PINSEL Public Types + * @{ + */ + +/** @brief Pin configuration structure */ +typedef struct +{ + uint8_t Portnum; /**< Port Number, should be PINSEL_PORT_x, + where x should be in range from 0 to 4 */ + uint8_t Pinnum; /**< Pin Number, should be PINSEL_PIN_x, + where x should be in range from 0 to 31 */ + uint8_t Funcnum; /**< Function Number, should be PINSEL_FUNC_x, + where x should be in range from 0 to 3 */ + uint8_t Pinmode; /**< Pin Mode, should be: + - PINSEL_PINMODE_PULLUP: Internal pull-up resistor + - PINSEL_PINMODE_TRISTATE: Tri-state + - PINSEL_PINMODE_PULLDOWN: Internal pull-down resistor */ + uint8_t OpenDrain; /**< OpenDrain mode, should be: + - PINSEL_PINMODE_NORMAL: Pin is in the normal (not open drain) mode + - PINSEL_PINMODE_OPENDRAIN: Pin is in the open drain mode */ +} PINSEL_CFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup PINSEL_Public_Functions PINSEL Public Functions + * @{ + */ + +void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg); +void PINSEL_ConfigTraceFunc (FunctionalState NewState); +void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_PINSEL_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_pwm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_pwm.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,533 @@ +/***********************************************************************//** + * @file lpc17xx_pwm.c + * @brief Contains all functions support for PWM firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_pwm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_pwm.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,330 @@ +/***********************************************************************//** + * @file lpc17xx_pwm.h + * @brief Contains all macro definitions and function prototypes + * support for PWM firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup PWM PWM + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_PWM_H_ +#define LPC17XX_PWM_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup PWM_Private_Macros PWM Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/********************************************************************** +* IR register definitions +**********************************************************************/ +/** Interrupt flag for PWM match channel for 6 channel */ +#define PWM_IR_PWMMRn(n) ((uint32_t)((n<4)?(1<<n):(1<<(n+4)))) +/** Interrupt flag for capture input */ +#define PWM_IR_PWMCAPn(n) ((uint32_t)(1<<(n+4))) +/** IR register mask */ +#define PWM_IR_BITMASK ((uint32_t)(0x0000073F)) + +/********************************************************************** +* TCR register definitions +**********************************************************************/ +/** TCR register mask */ +#define PWM_TCR_BITMASK ((uint32_t)(0x0000000B)) +#define PWM_TCR_COUNTER_ENABLE ((uint32_t)(1<<0)) /*!< PWM Counter Enable */ +#define PWM_TCR_COUNTER_RESET ((uint32_t)(1<<1)) /*!< PWM Counter Reset */ +#define PWM_TCR_PWM_ENABLE ((uint32_t)(1<<3)) /*!< PWM Enable */ + +/********************************************************************** +* CTCR register definitions +**********************************************************************/ +/** CTCR register mask */ +#define PWM_CTCR_BITMASK ((uint32_t)(0x0000000F)) +/** PWM Counter-Timer Mode */ +#define PWM_CTCR_MODE(n) ((uint32_t)(n&0x03)) +/** PWM Capture input select */ +#define PWM_CTCR_SELECT_INPUT(n) ((uint32_t)((n&0x03)<<2)) + +/********************************************************************** +* MCR register definitions +**********************************************************************/ +/** MCR register mask */ +#define PWM_MCR_BITMASK ((uint32_t)(0x001FFFFF)) +/** generate a PWM interrupt when a MATCHn occurs */ +#define PWM_MCR_INT_ON_MATCH(n) ((uint32_t)(1<<(((n&0x7)<<1)+(n&0x07)))) +/** reset the PWM when a MATCHn occurs */ +#define PWM_MCR_RESET_ON_MATCH(n) ((uint32_t)(1<<(((n&0x7)<<1)+(n&0x07)+1))) +/** stop the PWM when a MATCHn occurs */ +#define PWM_MCR_STOP_ON_MATCH(n) ((uint32_t)(1<<(((n&0x7)<<1)+(n&0x07)+2))) + +/********************************************************************** +* CCR register definitions +**********************************************************************/ +/** CCR register mask */ +#define PWM_CCR_BITMASK ((uint32_t)(0x0000003F)) +/** PCAPn is rising edge sensitive */ +#define PWM_CCR_CAP_RISING(n) ((uint32_t)(1<<(((n&0x2)<<1)+(n&0x1)))) +/** PCAPn is falling edge sensitive */ +#define PWM_CCR_CAP_FALLING(n) ((uint32_t)(1<<(((n&0x2)<<1)+(n&0x1)+1))) +/** PWM interrupt is generated on a PCAP event */ +#define PWM_CCR_INT_ON_CAP(n) ((uint32_t)(1<<(((n&0x2)<<1)+(n&0x1)+2))) + +/********************************************************************** +* PCR register definitions +**********************************************************************/ +/** PCR register mask */ +#define PWM_PCR_BITMASK (uint32_t)0x00007E7C +/** PWM output n is a single edge controlled output */ +#define PWM_PCR_PWMSELn(n) ((uint32_t)(((n&0x7)<2) ? 0 : (1<<n))) +/** enable PWM output n */ +#define PWM_PCR_PWMENAn(n) ((uint32_t)(((n&0x7)<1) ? 0 : (1<<(n+8)))) + +/********************************************************************** +* LER register definitions +**********************************************************************/ +/** LER register mask*/ +#define PWM_LER_BITMASK ((uint32_t)(0x0000007F)) +/** PWM MATCHn register update control */ +#define PWM_LER_EN_MATCHn_LATCH(n) ((uint32_t)((n<7) ? (1<<n) : 0)) + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid PWM peripheral or not */ +#define PARAM_PWMx(n) (((uint32_t *)n)==((uint32_t *)LPC_PWM1)) + +/** Macro check PWM1 match channel value */ +#define PARAM_PWM1_MATCH_CHANNEL(n) ((n)<=6) + +/** Macro check PWM1 channel value */ +#define PARAM_PWM1_CHANNEL(n) ((n>=1) && (n<=6)) + +/** Macro check PWM1 edge channel mode */ +#define PARAM_PWM1_EDGE_MODE_CHANNEL(n) ((n>=2) && (n<=6)) + +/** Macro check PWM1 capture channel mode */ +#define PARAM_PWM1_CAPTURE_CHANNEL(n) ((n==0) || (n==1)) + +/** Macro check PWM1 interrupt status type */ +#define PARAM_PWM_INTSTAT(n) ((n==PWM_INTSTAT_MR0) || (n==PWM_INTSTAT_MR1) || (n==PWM_INTSTAT_MR2) \ +|| (n==PWM_INTSTAT_MR3) || (n==PWM_INTSTAT_MR4) || (n==PWM_INTSTAT_MR5) \ +|| (n==PWM_INTSTAT_MR6) || (n==PWM_INTSTAT_CAP0) || (n==PWM_INTSTAT_CAP1)) +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup PWM_Public_Types PWM Public Types + * @{ + */ + +/** @brief Configuration structure in PWM TIMER mode */ +typedef struct { + + uint8_t PrescaleOption; /**< Prescale option, should be: + - PWM_TIMER_PRESCALE_TICKVAL: Prescale in absolute value + - PWM_TIMER_PRESCALE_USVAL: Prescale in microsecond value + */ + uint8_t Reserved[3]; + uint32_t PrescaleValue; /**< Prescale value, 32-bit long, should be matched + with PrescaleOption + */ +} PWM_TIMERCFG_Type; + +/** @brief Configuration structure in PWM COUNTER mode */ +typedef struct { + + uint8_t CounterOption; /**< Counter Option, should be: + - PWM_COUNTER_RISING: Rising Edge + - PWM_COUNTER_FALLING: Falling Edge + - PWM_COUNTER_ANY: Both rising and falling mode + */ + uint8_t CountInputSelect; /**< Counter input select, should be: + - PWM_COUNTER_PCAP1_0: PWM Counter input selected is PCAP1.0 pin + - PWM_COUNTER_PCAP1_1: PWM Counter input selected is PCAP1.1 pin + */ + uint8_t Reserved[2]; +} PWM_COUNTERCFG_Type; + +/** @brief PWM Match channel configuration structure */ +typedef struct { + uint8_t MatchChannel; /**< Match channel, should be in range + from 0..6 */ + uint8_t IntOnMatch; /**< Interrupt On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t StopOnMatch; /**< Stop On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t ResetOnMatch; /**< Reset On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ +} PWM_MATCHCFG_Type; + + +/** @brief PWM Capture Input configuration structure */ +typedef struct { + uint8_t CaptureChannel; /**< Capture channel, should be in range + from 0..1 */ + uint8_t RisingEdge; /**< caption rising edge, should be: + - ENABLE: Enable rising edge. + - DISABLE: Disable this function. + */ + uint8_t FallingEdge; /**< caption falling edge, should be: + - ENABLE: Enable falling edge. + - DISABLE: Disable this function. + */ + uint8_t IntOnCaption; /**< Interrupt On caption, should be: + - ENABLE: Enable interrupt function. + - DISABLE: Disable this function. + */ +} PWM_CAPTURECFG_Type; + +/* Timer/Counter in PWM configuration type definition -----------------------------------*/ + +/** @brief PMW TC mode select option */ +typedef enum { + PWM_MODE_TIMER = 0, /*!< PWM using Timer mode */ + PWM_MODE_COUNTER, /*!< PWM using Counter mode */ +} PWM_TC_MODE_OPT; + +#define PARAM_PWM_TC_MODE(n) ((n==PWM_MODE_TIMER) || (n==PWM_MODE_COUNTER)) + + +/** @brief PWM Timer/Counter prescale option */ +typedef enum +{ + PWM_TIMER_PRESCALE_TICKVAL = 0, /*!< Prescale in absolute value */ + PWM_TIMER_PRESCALE_USVAL /*!< Prescale in microsecond value */ +} PWM_TIMER_PRESCALE_OPT; + +#define PARAM_PWM_TIMER_PRESCALE(n) ((n==PWM_TIMER_PRESCALE_TICKVAL) || (n==PWM_TIMER_PRESCALE_USVAL)) + + +/** @brief PWM Input Select in counter mode */ +typedef enum { + PWM_COUNTER_PCAP1_0 = 0, /*!< PWM Counter input selected is PCAP1.0 pin */ + PWM_COUNTER_PCAP1_1 /*!< PWM counter input selected is CAP1.1 pin */ +} PWM_COUNTER_INPUTSEL_OPT; + +#define PARAM_PWM_COUNTER_INPUTSEL(n) ((n==PWM_COUNTER_PCAP1_0) || (n==PWM_COUNTER_PCAP1_1)) + +/** @brief PWM Input Edge Option in counter mode */ +typedef enum { + PWM_COUNTER_RISING = 1, /*!< Rising edge mode */ + PWM_COUNTER_FALLING = 2, /*!< Falling edge mode */ + PWM_COUNTER_ANY = 3 /*!< Both rising and falling mode */ +} PWM_COUNTER_EDGE_OPT; + +#define PARAM_PWM_COUNTER_EDGE(n) ((n==PWM_COUNTER_RISING) || (n==PWM_COUNTER_FALLING) \ +|| (n==PWM_COUNTER_ANY)) + + +/* PWM configuration type definition ----------------------------------------------------- */ +/** @brief PWM operating mode options */ +typedef enum { + PWM_CHANNEL_SINGLE_EDGE, /*!< PWM Channel Single edge mode */ + PWM_CHANNEL_DUAL_EDGE /*!< PWM Channel Dual edge mode */ +} PWM_CHANNEL_EDGE_OPT; + +#define PARAM_PWM_CHANNEL_EDGE(n) ((n==PWM_CHANNEL_SINGLE_EDGE) || (n==PWM_CHANNEL_DUAL_EDGE)) + + +/** @brief PWM update type */ +typedef enum { + PWM_MATCH_UPDATE_NOW = 0, /**< PWM Match Channel Update Now */ + PWM_MATCH_UPDATE_NEXT_RST /**< PWM Match Channel Update on next + PWM Counter resetting */ +} PWM_MATCH_UPDATE_OPT; + +#define PARAM_PWM_MATCH_UPDATE(n) ((n==PWM_MATCH_UPDATE_NOW) || (n==PWM_MATCH_UPDATE_NEXT_RST)) + + +/** @brief PWM interrupt status type definition ----------------------------------------------------- */ +/** @brief PWM Interrupt status type */ +typedef enum +{ + PWM_INTSTAT_MR0 = PWM_IR_PWMMRn(0), /**< Interrupt flag for PWM match channel 0 */ + PWM_INTSTAT_MR1 = PWM_IR_PWMMRn(1), /**< Interrupt flag for PWM match channel 1 */ + PWM_INTSTAT_MR2 = PWM_IR_PWMMRn(2), /**< Interrupt flag for PWM match channel 2 */ + PWM_INTSTAT_MR3 = PWM_IR_PWMMRn(3), /**< Interrupt flag for PWM match channel 3 */ + PWM_INTSTAT_CAP0 = PWM_IR_PWMCAPn(0), /**< Interrupt flag for capture input 0 */ + PWM_INTSTAT_CAP1 = PWM_IR_PWMCAPn(1), /**< Interrupt flag for capture input 1 */ + PWM_INTSTAT_MR4 = PWM_IR_PWMMRn(4), /**< Interrupt flag for PWM match channel 4 */ + PWM_INTSTAT_MR6 = PWM_IR_PWMMRn(5), /**< Interrupt flag for PWM match channel 5 */ + PWM_INTSTAT_MR5 = PWM_IR_PWMMRn(6), /**< Interrupt flag for PWM match channel 6 */ +}PWM_INTSTAT_TYPE; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup PWM_Public_Functions PWM Public Functions + * @{ + */ + +void PWM_PinConfig(LPC_PWM_TypeDef *PWMx, uint8_t PWM_Channel, uint8_t PinselOption); +IntStatus PWM_GetIntStatus(LPC_PWM_TypeDef *PWMx, uint32_t IntFlag); +void PWM_ClearIntPending(LPC_PWM_TypeDef *PWMx, uint32_t IntFlag); +void PWM_ConfigStructInit(uint8_t PWMTimerCounterMode, void *PWM_InitStruct); +void PWM_Init(LPC_PWM_TypeDef *PWMx, uint32_t PWMTimerCounterMode, void *PWM_ConfigStruct); +void PWM_DeInit (LPC_PWM_TypeDef *PWMx); +void PWM_Cmd(LPC_PWM_TypeDef *PWMx, FunctionalState NewState); +void PWM_CounterCmd(LPC_PWM_TypeDef *PWMx, FunctionalState NewState); +void PWM_ResetCounter(LPC_PWM_TypeDef *PWMx); +void PWM_ConfigMatch(LPC_PWM_TypeDef *PWMx, PWM_MATCHCFG_Type *PWM_MatchConfigStruct); +void PWM_ConfigCapture(LPC_PWM_TypeDef *PWMx, PWM_CAPTURECFG_Type *PWM_CaptureConfigStruct); +uint32_t PWM_GetCaptureValue(LPC_PWM_TypeDef *PWMx, uint8_t CaptureChannel); +void PWM_MatchUpdate(LPC_PWM_TypeDef *PWMx, uint8_t MatchChannel, \ + uint32_t MatchValue, uint8_t UpdateType); +void PWM_ChannelConfig(LPC_PWM_TypeDef *PWMx, uint8_t PWMChannel, uint8_t ModeOption); +void PWM_ChannelCmd(LPC_PWM_TypeDef *PWMx, uint8_t PWMChannel, FunctionalState NewState); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_PWM_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_qei.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_qei.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,502 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_qei.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_qei.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,412 @@ +/***********************************************************************//** + * @file lpc17xx_qei.h + * @brief Contains all macro definitions and function prototypes + * support for QEI firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup QEI QEI + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_QEI_H_ +#define LPC17XX_QEI_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup QEI_Public_Macros QEI Public Macros + * @{ + */ + +/* QEI Reset types */ +#define QEI_RESET_POS QEI_CON_RESP /**< Reset position counter */ +#define QEI_RESET_POSOnIDX QEI_CON_RESPI /**< Reset Posistion Counter on Index */ +#define QEI_RESET_VEL QEI_CON_RESV /**< Reset Velocity */ +#define QEI_RESET_IDX QEI_CON_RESI /**< Reset Index Counter */ + +/* QEI Direction Invert Type Option */ +#define QEI_DIRINV_NONE ((uint32_t)(0)) /**< Direction is not inverted */ +#define QEI_DIRINV_CMPL ((uint32_t)(1)) /**< Direction is complemented */ + +/* QEI Signal Mode Option */ +#define QEI_SIGNALMODE_QUAD ((uint32_t)(0)) /**< Signal operation: Quadrature phase mode */ +#define QEI_SIGNALMODE_CLKDIR ((uint32_t)(1)) /**< Signal operation: Clock/Direction mode */ + +/* QEI Capture Mode Option */ +#define QEI_CAPMODE_2X ((uint32_t)(0)) /**< Capture mode: Only Phase-A edges are counted (2X) */ +#define QEI_CAPMODE_4X ((uint32_t)(1)) /**< Capture mode: BOTH PhA and PhB edges are counted (4X)*/ + +/* QEI Invert Index Signal Option */ +#define QEI_INVINX_NONE ((uint32_t)(0)) /**< Invert Index signal option: None */ +#define QEI_INVINX_EN ((uint32_t)(1)) /**< Invert Index signal option: Enable */ + +/* QEI timer reload option */ +#define QEI_TIMERRELOAD_TICKVAL ((uint8_t)(0)) /**< Reload value in absolute value */ +#define QEI_TIMERRELOAD_USVAL ((uint8_t)(1)) /**< Reload value in microsecond value */ + +/* QEI Flag Status type */ +#define QEI_STATUS_DIR ((uint32_t)(1<<0)) /**< Direction status */ + +/* QEI Compare Position channel option */ +#define QEI_COMPPOS_CH_0 ((uint8_t)(0)) /**< QEI compare position channel 0 */ +#define QEI_COMPPOS_CH_1 ((uint8_t)(1)) /**< QEI compare position channel 1 */ +#define QEI_COMPPOS_CH_2 ((uint8_t)(2)) /**< QEI compare position channel 2 */ + +/* QEI interrupt flag type */ +#define QEI_INTFLAG_INX_Int ((uint32_t)(1<<0)) /**< index pulse was detected interrupt */ +#define QEI_INTFLAG_TIM_Int ((uint32_t)(1<<1)) /**< Velocity timer over flow interrupt */ +#define QEI_INTFLAG_VELC_Int ((uint32_t)(1<<2)) /**< Capture velocity is less than compare interrupt */ +#define QEI_INTFLAG_DIR_Int ((uint32_t)(1<<3)) /**< Change of direction interrupt */ +#define QEI_INTFLAG_ERR_Int ((uint32_t)(1<<4)) /**< An encoder phase error interrupt */ +#define QEI_INTFLAG_ENCLK_Int ((uint32_t)(1<<5)) /**< An encoder clock pulse was detected interrupt */ +#define QEI_INTFLAG_POS0_Int ((uint32_t)(1<<6)) /**< position 0 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_POS1_Int ((uint32_t)(1<<7)) /**< position 1 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_POS2_Int ((uint32_t)(1<<8)) /**< position 2 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_REV_Int ((uint32_t)(1<<9)) /**< Index compare value is equal to the current + index count interrupt */ +#define QEI_INTFLAG_POS0REV_Int ((uint32_t)(1<<10)) /**< Combined position 0 and revolution count interrupt */ +#define QEI_INTFLAG_POS1REV_Int ((uint32_t)(1<<11)) /**< Combined position 1 and revolution count interrupt */ +#define QEI_INTFLAG_POS2REV_Int ((uint32_t)(1<<12)) /**< Combined position 2 and revolution count interrupt */ + +/** + * @} + */ + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup QEI_Private_Macros QEI Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/* Quadrature Encoder Interface Control Register Definition --------------------- */ +/*********************************************************************//** + * Macro defines for QEI Control register + **********************************************************************/ +#define QEI_CON_RESP ((uint32_t)(1<<0)) /**< Reset position counter */ +#define QEI_CON_RESPI ((uint32_t)(1<<1)) /**< Reset Posistion Counter on Index */ +#define QEI_CON_RESV ((uint32_t)(1<<2)) /**< Reset Velocity */ +#define QEI_CON_RESI ((uint32_t)(1<<3)) /**< Reset Index Counter */ +#define QEI_CON_BITMASK ((uint32_t)(0x0F)) /**< QEI Control register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Configuration register + **********************************************************************/ +#define QEI_CONF_DIRINV ((uint32_t)(1<<0)) /**< Direction Invert */ +#define QEI_CONF_SIGMODE ((uint32_t)(1<<1)) /**< Signal mode */ +#define QEI_CONF_CAPMODE ((uint32_t)(1<<2)) /**< Capture mode */ +#define QEI_CONF_INVINX ((uint32_t)(1<<3)) /**< Invert index */ +#define QEI_CONF_BITMASK ((uint32_t)(0x0F)) /**< QEI Configuration register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Status register + **********************************************************************/ +#define QEI_STAT_DIR ((uint32_t)(1<<0)) /**< Direction bit */ +#define QEI_STAT_BITMASK ((uint32_t)(1<<0)) /**< QEI status register bit-mask */ + +/* Quadrature Encoder Interface Interrupt registers definitions --------------------- */ +/*********************************************************************//** + * Macro defines for QEI Interrupt Status register + **********************************************************************/ +#define QEI_INTSTAT_INX_Int ((uint32_t)(1<<0)) /**< Indicates that an index pulse was detected */ +#define QEI_INTSTAT_TIM_Int ((uint32_t)(1<<1)) /**< Indicates that a velocity timer overflow occurred */ +#define QEI_INTSTAT_VELC_Int ((uint32_t)(1<<2)) /**< Indicates that capture velocity is less than compare velocity */ +#define QEI_INTSTAT_DIR_Int ((uint32_t)(1<<3)) /**< Indicates that a change of direction was detected */ +#define QEI_INTSTAT_ERR_Int ((uint32_t)(1<<4)) /**< Indicates that an encoder phase error was detected */ +#define QEI_INTSTAT_ENCLK_Int ((uint32_t)(1<<5)) /**< Indicates that and encoder clock pulse was detected */ +#define QEI_INTSTAT_POS0_Int ((uint32_t)(1<<6)) /**< Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTSTAT_POS1_Int ((uint32_t)(1<<7)) /**< Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTSTAT_POS2_Int ((uint32_t)(1<<8)) /**< Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTSTAT_REV_Int ((uint32_t)(1<<9)) /**< Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTSTAT_POS0REV_Int ((uint32_t)(1<<10)) /**< Combined position 0 and revolution count interrupt. Set when + both the POS0_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_POS1REV_Int ((uint32_t)(1<<11)) /**< Combined position 1 and revolution count interrupt. Set when + both the POS1_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_POS2REV_Int ((uint32_t)(1<<12)) /**< Combined position 2 and revolution count interrupt. Set when + both the POS2_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Status register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Set register + **********************************************************************/ +#define QEI_INTSET_INX_Int ((uint32_t)(1<<0)) /**< Set Bit Indicates that an index pulse was detected */ +#define QEI_INTSET_TIM_Int ((uint32_t)(1<<1)) /**< Set Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTSET_VELC_Int ((uint32_t)(1<<2)) /**< Set Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTSET_DIR_Int ((uint32_t)(1<<3)) /**< Set Bit Indicates that a change of direction was detected */ +#define QEI_INTSET_ERR_Int ((uint32_t)(1<<4)) /**< Set Bit Indicates that an encoder phase error was detected */ +#define QEI_INTSET_ENCLK_Int ((uint32_t)(1<<5)) /**< Set Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTSET_POS0_Int ((uint32_t)(1<<6)) /**< Set Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTSET_POS1_Int ((uint32_t)(1<<7)) /**< Set Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTSET_POS2_Int ((uint32_t)(1<<8)) /**< Set Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTSET_REV_Int ((uint32_t)(1<<9)) /**< Set Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTSET_POS0REV_Int ((uint32_t)(1<<10)) /**< Set Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTSET_POS1REV_Int ((uint32_t)(1<<11)) /**< Set Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTSET_POS2REV_Int ((uint32_t)(1<<12)) /**< Set Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTSET_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Set register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Clear register + **********************************************************************/ +#define QEI_INTCLR_INX_Int ((uint32_t)(1<<0)) /**< Clear Bit Indicates that an index pulse was detected */ +#define QEI_INTCLR_TIM_Int ((uint32_t)(1<<1)) /**< Clear Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTCLR_VELC_Int ((uint32_t)(1<<2)) /**< Clear Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTCLR_DIR_Int ((uint32_t)(1<<3)) /**< Clear Bit Indicates that a change of direction was detected */ +#define QEI_INTCLR_ERR_Int ((uint32_t)(1<<4)) /**< Clear Bit Indicates that an encoder phase error was detected */ +#define QEI_INTCLR_ENCLK_Int ((uint32_t)(1<<5)) /**< Clear Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTCLR_POS0_Int ((uint32_t)(1<<6)) /**< Clear Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTCLR_POS1_Int ((uint32_t)(1<<7)) /**< Clear Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTCLR_POS2_Int ((uint32_t)(1<<8)) /**< Clear Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTCLR_REV_Int ((uint32_t)(1<<9)) /**< Clear Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTCLR_POS0REV_Int ((uint32_t)(1<<10)) /**< Clear Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTCLR_POS1REV_Int ((uint32_t)(1<<11)) /**< Clear Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTCLR_POS2REV_Int ((uint32_t)(1<<12)) /**< Clear Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTCLR_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Clear register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable register + **********************************************************************/ +#define QEI_INTEN_INX_Int ((uint32_t)(1<<0)) /**< Enabled Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_INTEN_TIM_Int ((uint32_t)(1<<1)) /**< Enabled Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTEN_VELC_Int ((uint32_t)(1<<2)) /**< Enabled Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTEN_DIR_Int ((uint32_t)(1<<3)) /**< Enabled Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_INTEN_ERR_Int ((uint32_t)(1<<4)) /**< Enabled Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_INTEN_ENCLK_Int ((uint32_t)(1<<5)) /**< Enabled Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTEN_POS0_Int ((uint32_t)(1<<6)) /**< Enabled Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTEN_POS1_Int ((uint32_t)(1<<7)) /**< Enabled Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTEN_POS2_Int ((uint32_t)(1<<8)) /**< Enabled Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTEN_REV_Int ((uint32_t)(1<<9)) /**< Enabled Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTEN_POS0REV_Int ((uint32_t)(1<<10)) /**< Enabled Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTEN_POS1REV_Int ((uint32_t)(1<<11)) /**< Enabled Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTEN_POS2REV_Int ((uint32_t)(1<<12)) /**< Enabled Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTEN_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable Set register + **********************************************************************/ +#define QEI_IESET_INX_Int ((uint32_t)(1<<0)) /**< Set Enable Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_IESET_TIM_Int ((uint32_t)(1<<1)) /**< Set Enable Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_IESET_VELC_Int ((uint32_t)(1<<2)) /**< Set Enable Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_IESET_DIR_Int ((uint32_t)(1<<3)) /**< Set Enable Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_IESET_ERR_Int ((uint32_t)(1<<4)) /**< Set Enable Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_IESET_ENCLK_Int ((uint32_t)(1<<5)) /**< Set Enable Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_IESET_POS0_Int ((uint32_t)(1<<6)) /**< Set Enable Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_IESET_POS1_Int ((uint32_t)(1<<7)) /**< Set Enable Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_IESET_POS2_Int ((uint32_t)(1<<8)) /**< Set Enable Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_IESET_REV_Int ((uint32_t)(1<<9)) /**< Set Enable Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_IESET_POS0REV_Int ((uint32_t)(1<<10)) /**< Set Enable Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_IESET_POS1REV_Int ((uint32_t)(1<<11)) /**< Set Enable Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_IESET_POS2REV_Int ((uint32_t)(1<<12)) /**< Set Enable Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_IESET_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable Set register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable Clear register + **********************************************************************/ +#define QEI_IECLR_INX_Int ((uint32_t)(1<<0)) /**< Clear Enabled Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_IECLR_TIM_Int ((uint32_t)(1<<1)) /**< Clear Enabled Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_IECLR_VELC_Int ((uint32_t)(1<<2)) /**< Clear Enabled Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_IECLR_DIR_Int ((uint32_t)(1<<3)) /**< Clear Enabled Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_IECLR_ERR_Int ((uint32_t)(1<<4)) /**< Clear Enabled Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_IECLR_ENCLK_Int ((uint32_t)(1<<5)) /**< Clear Enabled Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_IECLR_POS0_Int ((uint32_t)(1<<6)) /**< Clear Enabled Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_IECLR_POS1_Int ((uint32_t)(1<<7)) /**< Clear Enabled Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_IECLR_POS2_Int ((uint32_t)(1<<8)) /**< Clear Enabled Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_IECLR_REV_Int ((uint32_t)(1<<9)) /**< Clear Enabled Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_IECLR_POS0REV_Int ((uint32_t)(1<<10)) /**< Clear Enabled Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_IECLR_POS1REV_Int ((uint32_t)(1<<11)) /**< Clear Enabled Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_IECLR_POS2REV_Int ((uint32_t)(1<<12)) /**< Clear Enabled Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_IECLR_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable Clear register bit-mask */ + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/* Macro check QEI peripheral */ +#define PARAM_QEIx(n) ((n==LPC_QEI)) + +/* Macro check QEI reset type */ +#define PARAM_QEI_RESET(n) ((n==QEI_CON_RESP) \ +|| (n==QEI_RESET_POSOnIDX) \ +|| (n==QEI_RESET_VEL) \ +|| (n==QEI_RESET_IDX)) + +/* Macro check QEI Direction invert mode */ +#define PARAM_QEI_DIRINV(n) ((n==QEI_DIRINV_NONE) || (n==QEI_DIRINV_CMPL)) + +/* Macro check QEI signal mode */ +#define PARAM_QEI_SIGNALMODE(n) ((n==QEI_SIGNALMODE_QUAD) || (n==QEI_SIGNALMODE_CLKDIR)) + +/* Macro check QEI Capture mode */ +#define PARAM_QEI_CAPMODE(n) ((n==QEI_CAPMODE_2X) || (n==QEI_CAPMODE_4X)) + +/* Macro check QEI Invert index mode */ +#define PARAM_QEI_INVINX(n) ((n==QEI_INVINX_NONE) || (n==QEI_INVINX_EN)) + +/* Macro check QEI Direction invert mode */ +#define PARAM_QEI_TIMERRELOAD(n) ((n==QEI_TIMERRELOAD_TICKVAL) || (n==QEI_TIMERRELOAD_USVAL)) + +/* Macro check QEI status type */ +#define PARAM_QEI_STATUS(n) ((n==QEI_STATUS_DIR)) + +/* Macro check QEI combine position type */ +#define PARAM_QEI_COMPPOS_CH(n) ((n==QEI_COMPPOS_CH_0) || (n==QEI_COMPPOS_CH_1) || (n==QEI_COMPPOS_CH_2)) + +/* Macro check QEI interrupt flag type */ +#define PARAM_QEI_INTFLAG(n) ((n==QEI_INTFLAG_INX_Int) \ +|| (n==QEI_INTFLAG_TIM_Int) \ +|| (n==QEI_INTFLAG_VELC_Int) \ +|| (n==QEI_INTFLAG_DIR_Int) \ +|| (n==QEI_INTFLAG_ERR_Int) \ +|| (n==QEI_INTFLAG_ENCLK_Int) \ +|| (n==QEI_INTFLAG_POS0_Int) \ +|| (n==QEI_INTFLAG_POS1_Int) \ +|| (n==QEI_INTFLAG_POS2_Int) \ +|| (n==QEI_INTFLAG_REV_Int) \ +|| (n==QEI_INTFLAG_POS0REV_Int) \ +|| (n==QEI_INTFLAG_POS1REV_Int) \ +|| (n==QEI_INTFLAG_POS2REV_Int)) +/** + * @} + */ + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup QEI_Public_Types QEI Public Types + * @{ + */ + +/** + * @brief QEI Configuration structure type definition + */ +typedef struct { + uint32_t DirectionInvert :1; /**< Direction invert option: + - QEI_DIRINV_NONE: QEI Direction is normal + - QEI_DIRINV_CMPL: QEI Direction is complemented + */ + uint32_t SignalMode :1; /**< Signal mode Option: + - QEI_SIGNALMODE_QUAD: Signal is in Quadrature phase mode + - QEI_SIGNALMODE_CLKDIR: Signal is in Clock/Direction mode + */ + uint32_t CaptureMode :1; /**< Capture Mode Option: + - QEI_CAPMODE_2X: Only Phase-A edges are counted (2X) + - QEI_CAPMODE_4X: BOTH Phase-A and Phase-B edges are counted (4X) + */ + uint32_t InvertIndex :1; /**< Invert Index Option: + - QEI_INVINX_NONE: the sense of the index input is normal + - QEI_INVINX_EN: inverts the sense of the index input + */ +} QEI_CFG_Type; + +/** + * @brief Timer Reload Configuration structure type definition + */ +typedef struct { + + uint8_t ReloadOption; /**< Velocity Timer Reload Option, should be: + - QEI_TIMERRELOAD_TICKVAL: Reload value in absolute value + - QEI_TIMERRELOAD_USVAL: Reload value in microsecond value + */ + uint8_t Reserved[3]; + uint32_t ReloadValue; /**< Velocity Timer Reload Value, 32-bit long, should be matched + with Velocity Timer Reload Option + */ +} QEI_RELOADCFG_Type; + +/** + * @} + */ + + + + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup QEI_Public_Functions QEI Public Functions + * @{ + */ + +void QEI_Reset(LPC_QEI_TypeDef *QEIx, uint32_t ulResetType); +void QEI_Init(LPC_QEI_TypeDef *QEIx, QEI_CFG_Type *QEI_ConfigStruct); +void QEI_ConfigStructInit(QEI_CFG_Type *QIE_InitStruct); +void QEI_DeInit(LPC_QEI_TypeDef *QEIx); +FlagStatus QEI_GetStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulFlagType); +uint32_t QEI_GetPosition(LPC_QEI_TypeDef *QEIx); +void QEI_SetMaxPosition(LPC_QEI_TypeDef *QEIx, uint32_t ulMaxPos); +void QEI_SetPositionComp(LPC_QEI_TypeDef *QEIx, uint8_t bPosCompCh, uint32_t ulPosComp); +uint32_t QEI_GetIndex(LPC_QEI_TypeDef *QEIx); +void QEI_SetIndexComp(LPC_QEI_TypeDef *QEIx, uint32_t ulIndexComp); +void QEI_SetTimerReload(LPC_QEI_TypeDef *QEIx, QEI_RELOADCFG_Type *QEIReloadStruct); +uint32_t QEI_GetTimer(LPC_QEI_TypeDef *QEIx); +uint32_t QEI_GetVelocity(LPC_QEI_TypeDef *QEIx); +uint32_t QEI_GetVelocityCap(LPC_QEI_TypeDef *QEIx); +void QEI_SetVelocityComp(LPC_QEI_TypeDef *QEIx, uint32_t ulVelComp); +void QEI_SetDigiFilter(LPC_QEI_TypeDef *QEIx, uint32_t ulSamplingPulse); +FlagStatus QEI_GetIntStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType); +void QEI_IntCmd(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType, FunctionalState NewState); +void QEI_IntSet(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType); +void QEI_IntClear(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType); +uint32_t QEI_CalculateRPM(LPC_QEI_TypeDef *QEIx, uint32_t ulVelCapValue, uint32_t ulPPR); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_QEI_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_rit.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_rit.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,187 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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) +{ + uint8_t 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 (IntStatus)result; +} + +/** + * @} + */ + +#endif /* _RIT */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_rit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_rit.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,100 @@ +/***********************************************************************//** + * @file lpc17xx_rit.h + * @brief Contains all macro definitions and function prototypes + * support for RIT firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup RIT RIT + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_RIT_H_ +#define LPC17XX_RIT_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup RIT_Private_Macros RIT Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for RIT control register + **********************************************************************/ +/** Set interrupt flag when the counter value equals the masked compare value */ +#define RIT_CTRL_INTEN ((uint32_t) (1)) +/** Set timer enable clear to 0 when the counter value equals the masked compare value */ +#define RIT_CTRL_ENCLR ((uint32_t) _BIT(1)) +/** Set timer enable on debug */ +#define RIT_CTRL_ENBR ((uint32_t) _BIT(2)) +/** Set timer enable */ +#define RIT_CTRL_TEN ((uint32_t) _BIT(3)) + +/** Macro to determine if it is valid RIT peripheral */ +#define PARAM_RITx(n) (((uint32_t *)n)==((uint32_t *)LPC_RIT)) +/** + * @} + */ + + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup RIT_Public_Functions RIT Public Functions + * @{ + */ +/* RIT Init/DeInit functions */ +void RIT_Init(LPC_RIT_TypeDef *RITx); +void RIT_DeInit(LPC_RIT_TypeDef *RITx); + +/* RIT config timer functions */ +void RIT_TimerConfig(LPC_RIT_TypeDef *RITx, uint32_t time_interval); + +/* Enable/Disable RIT functions */ +void RIT_TimerClearCmd(LPC_RIT_TypeDef *RITx, FunctionalState NewState); +void RIT_Cmd(LPC_RIT_TypeDef *RITx, FunctionalState NewState); +void RIT_TimerDebugCmd(LPC_RIT_TypeDef *RITx, FunctionalState NewState); + +/* RIT Interrupt functions */ +IntStatus RIT_GetIntStatus(LPC_RIT_TypeDef *RITx); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_RIT_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_rtc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_rtc.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,771 @@ +/***********************************************************************//** + * @file lpc17xx_rtc.c + * @brief Contains all functions support for RTC firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 - 1) & 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_rtc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_rtc.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,302 @@ +/***********************************************************************//** + * @file lpc17xx_rtc.h + * @brief Contains all macro definitions and function prototypes + * support for RTC firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup RTC RTC + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_RTC_H_ +#define LPC17XX_RTC_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup RTC_Private_Macros RTC Private Macros + * @{ + */ + +/* ----------------------- BIT DEFINITIONS ----------------------------------- */ +/* Miscellaneous register group --------------------------------------------- */ +/********************************************************************** +* ILR register definitions +**********************************************************************/ +/** ILR register mask */ +#define RTC_ILR_BITMASK ((0x00000003)) +/** Bit inform the source interrupt is counter increment*/ +#define RTC_IRL_RTCCIF ((1<<0)) +/** Bit inform the source interrupt is alarm match*/ +#define RTC_IRL_RTCALF ((1<<1)) + +/********************************************************************** +* CCR register definitions +**********************************************************************/ +/** CCR register mask */ +#define RTC_CCR_BITMASK ((0x00000013)) +/** Clock enable */ +#define RTC_CCR_CLKEN ((1<<0)) +/** Clock reset */ +#define RTC_CCR_CTCRST ((1<<1)) +/** Calibration counter enable */ +#define RTC_CCR_CCALEN ((1<<4)) + +/********************************************************************** +* CIIR register definitions +**********************************************************************/ +/** Counter Increment Interrupt bit for second */ +#define RTC_CIIR_IMSEC ((1<<0)) +/** Counter Increment Interrupt bit for minute */ +#define RTC_CIIR_IMMIN ((1<<1)) +/** Counter Increment Interrupt bit for hour */ +#define RTC_CIIR_IMHOUR ((1<<2)) +/** Counter Increment Interrupt bit for day of month */ +#define RTC_CIIR_IMDOM ((1<<3)) +/** Counter Increment Interrupt bit for day of week */ +#define RTC_CIIR_IMDOW ((1<<4)) +/** Counter Increment Interrupt bit for day of year */ +#define RTC_CIIR_IMDOY ((1<<5)) +/** Counter Increment Interrupt bit for month */ +#define RTC_CIIR_IMMON ((1<<6)) +/** Counter Increment Interrupt bit for year */ +#define RTC_CIIR_IMYEAR ((1<<7)) +/** CIIR bit mask */ +#define RTC_CIIR_BITMASK ((0xFF)) + +/********************************************************************** +* AMR register definitions +**********************************************************************/ +/** Counter Increment Select Mask bit for second */ +#define RTC_AMR_AMRSEC ((1<<0)) +/** Counter Increment Select Mask bit for minute */ +#define RTC_AMR_AMRMIN ((1<<1)) +/** Counter Increment Select Mask bit for hour */ +#define RTC_AMR_AMRHOUR ((1<<2)) +/** Counter Increment Select Mask bit for day of month */ +#define RTC_AMR_AMRDOM ((1<<3)) +/** Counter Increment Select Mask bit for day of week */ +#define RTC_AMR_AMRDOW ((1<<4)) +/** Counter Increment Select Mask bit for day of year */ +#define RTC_AMR_AMRDOY ((1<<5)) +/** Counter Increment Select Mask bit for month */ +#define RTC_AMR_AMRMON ((1<<6)) +/** Counter Increment Select Mask bit for year */ +#define RTC_AMR_AMRYEAR ((1<<7)) +/** AMR bit mask */ +#define RTC_AMR_BITMASK ((0xFF)) + +/********************************************************************** +* RTC_AUX register definitions +**********************************************************************/ +/** RTC Oscillator Fail detect flag */ +#define RTC_AUX_RTC_OSCF ((1<<4)) + +/********************************************************************** +* RTC_AUXEN register definitions +**********************************************************************/ +/** Oscillator Fail Detect interrupt enable*/ +#define RTC_AUXEN_RTC_OSCFEN ((1<<4)) + +/* Consolidated time register group ----------------------------------- */ +/********************************************************************** +* Consolidated Time Register 0 definitions +**********************************************************************/ +#define RTC_CTIME0_SECONDS_MASK ((0x3F)) +#define RTC_CTIME0_MINUTES_MASK ((0x3F00)) +#define RTC_CTIME0_HOURS_MASK ((0x1F0000)) +#define RTC_CTIME0_DOW_MASK ((0x7000000)) + +/********************************************************************** +* Consolidated Time Register 1 definitions +**********************************************************************/ +#define RTC_CTIME1_DOM_MASK ((0x1F)) +#define RTC_CTIME1_MONTH_MASK ((0xF00)) +#define RTC_CTIME1_YEAR_MASK ((0xFFF0000)) + +/********************************************************************** +* Consolidated Time Register 2 definitions +**********************************************************************/ +#define RTC_CTIME2_DOY_MASK ((0xFFF)) + +/********************************************************************** +* Time Counter Group and Alarm register group +**********************************************************************/ +/** SEC register mask */ +#define RTC_SEC_MASK (0x0000003F) +/** MIN register mask */ +#define RTC_MIN_MASK (0x0000003F) +/** HOUR register mask */ +#define RTC_HOUR_MASK (0x0000001F) +/** DOM register mask */ +#define RTC_DOM_MASK (0x0000001F) +/** DOW register mask */ +#define RTC_DOW_MASK (0x00000007) +/** DOY register mask */ +#define RTC_DOY_MASK (0x000001FF) +/** MONTH register mask */ +#define RTC_MONTH_MASK (0x0000000F) +/** YEAR register mask */ +#define RTC_YEAR_MASK (0x00000FFF) + +#define RTC_SECOND_MAX 59 /*!< Maximum value of second */ +#define RTC_MINUTE_MAX 59 /*!< Maximum value of minute*/ +#define RTC_HOUR_MAX 23 /*!< Maximum value of hour*/ +#define RTC_MONTH_MIN 1 /*!< Minimum value of month*/ +#define RTC_MONTH_MAX 12 /*!< Maximum value of month*/ +#define RTC_DAYOFMONTH_MIN 1 /*!< Minimum value of day of month*/ +#define RTC_DAYOFMONTH_MAX 31 /*!< Maximum value of day of month*/ +#define RTC_DAYOFWEEK_MAX 6 /*!< Maximum value of day of week*/ +#define RTC_DAYOFYEAR_MIN 1 /*!< Minimum value of day of year*/ +#define RTC_DAYOFYEAR_MAX 366 /*!< Maximum value of day of year*/ +#define RTC_YEAR_MAX 4095 /*!< Maximum value of year*/ + +/********************************************************************** +* Calibration register +**********************************************************************/ +/* Calibration register */ +/** Calibration value */ +#define RTC_CALIBRATION_CALVAL_MASK ((0x1FFFF)) +/** Calibration direction */ +#define RTC_CALIBRATION_LIBDIR ((1<<17)) +/** Calibration max value */ +#define RTC_CALIBRATION_MAX ((0x20000)) +/** Calibration definitions */ +#define RTC_CALIB_DIR_FORWARD ((uint8_t)(0)) +#define RTC_CALIB_DIR_BACKWARD ((uint8_t)(1)) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid RTC peripheral */ +#define PARAM_RTCx(x) (((uint32_t *)x)==((uint32_t *)LPC_RTC)) + +/* Macro check RTC interrupt type */ +#define PARAM_RTC_INT(n) ((n==RTC_INT_COUNTER_INCREASE) || (n==RTC_INT_ALARM)) + +/* Macro check RTC time type */ +#define PARAM_RTC_TIMETYPE(n) ((n==RTC_TIMETYPE_SECOND) || (n==RTC_TIMETYPE_MINUTE) \ +|| (n==RTC_TIMETYPE_HOUR) || (n==RTC_TIMETYPE_DAYOFWEEK) \ +|| (n==RTC_TIMETYPE_DAYOFMONTH) || (n==RTC_TIMETYPE_DAYOFYEAR) \ +|| (n==RTC_TIMETYPE_MONTH) || (n==RTC_TIMETYPE_YEAR)) + +/* Macro check RTC calibration type */ +#define PARAM_RTC_CALIB_DIR(n) ((n==RTC_CALIB_DIR_FORWARD) || (n==RTC_CALIB_DIR_BACKWARD)) + +/* Macro check RTC GPREG type */ +#define PARAM_RTC_GPREG_CH(n) ((n)<=4) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup RTC_Public_Types RTC Public Types + * @{ + */ + +/** @brief Time structure definitions for easy manipulate the data */ +typedef struct { + uint32_t SEC; /*!< Seconds Register */ + uint32_t MIN; /*!< Minutes Register */ + uint32_t HOUR; /*!< Hours Register */ + uint32_t DOM; /*!< Day of Month Register */ + uint32_t DOW; /*!< Day of Week Register */ + uint32_t DOY; /*!< Day of Year Register */ + uint32_t MONTH; /*!< Months Register */ + uint32_t YEAR; /*!< Years Register */ +} RTC_TIME_Type; + +/** @brief RTC interrupt source */ +typedef enum { + RTC_INT_COUNTER_INCREASE = RTC_IRL_RTCCIF, /*!< Counter Increment Interrupt */ + RTC_INT_ALARM = RTC_IRL_RTCALF, /*!< The alarm interrupt */ +} RTC_INT_OPT; + + +/** @brief RTC time type option */ +typedef enum { + RTC_TIMETYPE_SECOND = 0, /*!< Second */ + RTC_TIMETYPE_MINUTE = 1, /*!< Month */ + RTC_TIMETYPE_HOUR = 2, /*!< Hour */ + RTC_TIMETYPE_DAYOFWEEK = 3, /*!< Day of week */ + RTC_TIMETYPE_DAYOFMONTH = 4, /*!< Day of month */ + RTC_TIMETYPE_DAYOFYEAR = 5, /*!< Day of year */ + RTC_TIMETYPE_MONTH = 6, /*!< Month */ + RTC_TIMETYPE_YEAR = 7, /*!< Year */ +} RTC_TIMETYPE_Num; + +/** + * @} + */ + + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup RTC_Public_Functions RTC Public Functions + * @{ + */ + +void RTC_Init (LPC_RTC_TypeDef *RTCx); +void RTC_DeInit(LPC_RTC_TypeDef *RTCx); +void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx); +void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState); +void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \ + FunctionalState NewState); +void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \ + FunctionalState NewState); +void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue); +uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype); +void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue); +uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype); +void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime); +IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType); +void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType); +void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState); +void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir); +void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value); +uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_RTC_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_spi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_spi.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,431 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = 0; + uint8_t *wdata8 = 0; + uint16_t *rdata16 = 0; + uint16_t *wdata16 = 0; + uint32_t stat = 0; + 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_spi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_spi.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,316 @@ +/***********************************************************************//** + * @file lpc17xx_spi.h + * @brief Contains all macro definitions and function prototypes + * support for SPI firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup SPI SPI + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_SPI_H_ +#define LPC17XX_SPI_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup SPI_Public_Macros SPI Public Macros + * @{ + */ + +/*********************************************************************//** + * SPI configuration parameter defines + **********************************************************************/ +/** Clock phase control bit */ +#define SPI_CPHA_FIRST ((uint32_t)(0)) +#define SPI_CPHA_SECOND ((uint32_t)(1<<3)) + +/** Clock polarity control bit */ +#define SPI_CPOL_HI ((uint32_t)(0)) +#define SPI_CPOL_LO ((uint32_t)(1<<4)) + +/** SPI master mode enable */ +#define SPI_SLAVE_MODE ((uint32_t)(0)) +#define SPI_MASTER_MODE ((uint32_t)(1<<5)) + +/** LSB enable bit */ +#define SPI_DATA_MSB_FIRST ((uint32_t)(0)) +#define SPI_DATA_LSB_FIRST ((uint32_t)(1<<6)) + +/** SPI data bit number defines */ +#define SPI_DATABIT_16 SPI_SPCR_BITS(0) /*!< Databit number = 16 */ +#define SPI_DATABIT_8 SPI_SPCR_BITS(0x08) /*!< Databit number = 8 */ +#define SPI_DATABIT_9 SPI_SPCR_BITS(0x09) /*!< Databit number = 9 */ +#define SPI_DATABIT_10 SPI_SPCR_BITS(0x0A) /*!< Databit number = 10 */ +#define SPI_DATABIT_11 SPI_SPCR_BITS(0x0B) /*!< Databit number = 11 */ +#define SPI_DATABIT_12 SPI_SPCR_BITS(0x0C) /*!< Databit number = 12 */ +#define SPI_DATABIT_13 SPI_SPCR_BITS(0x0D) /*!< Databit number = 13 */ +#define SPI_DATABIT_14 SPI_SPCR_BITS(0x0E) /*!< Databit number = 14 */ +#define SPI_DATABIT_15 SPI_SPCR_BITS(0x0F) /*!< Databit number = 15 */ + +/*********************************************************************//** + * SPI Status Flag defines + **********************************************************************/ +/** Slave abort */ +#define SPI_STAT_ABRT SPI_SPSR_ABRT +/** Mode fault */ +#define SPI_STAT_MODF SPI_SPSR_MODF +/** Read overrun */ +#define SPI_STAT_ROVR SPI_SPSR_ROVR +/** Write collision */ +#define SPI_STAT_WCOL SPI_SPSR_WCOL +/** SPI transfer complete flag */ +#define SPI_STAT_SPIF SPI_SPSR_SPIF + +/* SPI Status Implementation definitions */ +#define SPI_STAT_DONE (1UL<<8) /**< Done */ +#define SPI_STAT_ERROR (1UL<<9) /**< Error */ + +/** + * @} + */ + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup SPI_Private_Macros SPI Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for SPI Control Register + **********************************************************************/ +/** Bit enable, the SPI controller sends and receives the number + * of bits selected by bits 11:8 */ +#define SPI_SPCR_BIT_EN ((uint32_t)(1<<2)) +/** Clock phase control bit */ +#define SPI_SPCR_CPHA_SECOND ((uint32_t)(1<<3)) +/** Clock polarity control bit */ +#define SPI_SPCR_CPOL_LOW ((uint32_t)(1<<4)) +/** SPI master mode enable */ +#define SPI_SPCR_MSTR ((uint32_t)(1<<5)) +/** LSB enable bit */ +#define SPI_SPCR_LSBF ((uint32_t)(1<<6)) +/** SPI interrupt enable bit */ +#define SPI_SPCR_SPIE ((uint32_t)(1<<7)) +/** When bit 2 of this register is 1, this field controls the +number of bits per transfer */ +#define SPI_SPCR_BITS(n) ((n==0) ? ((uint32_t)0) : ((uint32_t)((n&0x0F)<<8))) +/** SPI Control bit mask */ +#define SPI_SPCR_BITMASK ((uint32_t)(0xFFC)) + +/*********************************************************************//** + * Macro defines for SPI Status Register + **********************************************************************/ +/** Slave abort */ +#define SPI_SPSR_ABRT ((uint32_t)(1<<3)) +/** Mode fault */ +#define SPI_SPSR_MODF ((uint32_t)(1<<4)) +/** Read overrun */ +#define SPI_SPSR_ROVR ((uint32_t)(1<<5)) +/** Write collision */ +#define SPI_SPSR_WCOL ((uint32_t)(1<<6)) +/** SPI transfer complete flag */ +#define SPI_SPSR_SPIF ((uint32_t)(1<<7)) +/** SPI Status bit mask */ +#define SPI_SPSR_BITMASK ((uint32_t)(0xF8)) + +/*********************************************************************//** + * Macro defines for SPI Data Register + **********************************************************************/ +/** SPI Data low bit-mask */ +#define SPI_SPDR_LO_MASK ((uint32_t)(0xFF)) +/** SPI Data high bit-mask */ +#define SPI_SPDR_HI_MASK ((uint32_t)(0xFF00)) +/** SPI Data bit-mask */ +#define SPI_SPDR_BITMASK ((uint32_t)(0xFFFF)) + +/*********************************************************************//** + * Macro defines for SPI Clock Counter Register + **********************************************************************/ +/** SPI clock counter setting */ +#define SPI_SPCCR_COUNTER(n) ((uint32_t)(n&0xFF)) +/** SPI clock counter bit-mask */ +#define SPI_SPCCR_BITMASK ((uint32_t)(0xFF)) + +/*********************************************************************** + * Macro defines for SPI Test Control Register + **********************************************************************/ +/** SPI Test bit */ +#define SPI_SPTCR_TEST_MASK ((uint32_t)(0xFE)) +/** SPI Test register bit mask */ +#define SPI_SPTCR_BITMASK ((uint32_t)(0xFE)) + +/*********************************************************************//** + * Macro defines for SPI Test Status Register + **********************************************************************/ +/** Slave abort */ +#define SPI_SPTSR_ABRT ((uint32_t)(1<<3)) +/** Mode fault */ +#define SPI_SPTSR_MODF ((uint32_t)(1<<4)) +/** Read overrun */ +#define SPI_SPTSR_ROVR ((uint32_t)(1<<5)) +/** Write collision */ +#define SPI_SPTSR_WCOL ((uint32_t)(1<<6)) +/** SPI transfer complete flag */ +#define SPI_SPTSR_SPIF ((uint32_t)(1<<7)) +/** SPI Status bit mask */ +#define SPI_SPTSR_MASKBIT ((uint32_t)(0xF8)) + +/*********************************************************************//** + * Macro defines for SPI Interrupt Register + **********************************************************************/ +/** SPI interrupt flag */ +#define SPI_SPINT_INTFLAG ((uint32_t)(1<<0)) +/** SPI interrupt register bit mask */ +#define SPI_SPINT_BITMASK ((uint32_t)(0x01)) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid SPI port number */ +#define PARAM_SPIx(n) (((uint32_t *)n)==((uint32_t *)LPC_SPI)) + +/** Macro check Clock phase control mode */ +#define PARAM_SPI_CPHA(n) ((n==SPI_CPHA_FIRST) || (n==SPI_CPHA_SECOND)) + +/** Macro check Clock polarity control mode */ +#define PARAM_SPI_CPOL(n) ((n==SPI_CPOL_HI) || (n==SPI_CPOL_LO)) + +/** Macro check master/slave mode */ +#define PARAM_SPI_MODE(n) ((n==SPI_SLAVE_MODE) || (n==SPI_MASTER_MODE)) + +/** Macro check LSB/MSB mode */ +#define PARAM_SPI_DATA_ORDER(n) ((n==SPI_DATA_MSB_FIRST) || (n==SPI_DATA_LSB_FIRST)) + +/** Macro check databit value */ +#define PARAM_SPI_DATABIT(n) ((n==SPI_DATABIT_16) || (n==SPI_DATABIT_8) \ +|| (n==SPI_DATABIT_9) || (n==SPI_DATABIT_10) \ +|| (n==SPI_DATABIT_11) || (n==SPI_DATABIT_12) \ +|| (n==SPI_DATABIT_13) || (n==SPI_DATABIT_14) \ +|| (n==SPI_DATABIT_15)) + +/** Macro check status flag */ +#define PARAM_SPI_STAT(n) ((n==SPI_STAT_ABRT) || (n==SPI_STAT_MODF) \ +|| (n==SPI_STAT_ROVR) || (n==SPI_STAT_WCOL) \ +|| (n==SPI_STAT_SPIF)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup SPI_Public_Types SPI Public Types + * @{ + */ + +/** @brief SPI configuration structure */ +typedef struct { + uint32_t Databit; /** Databit number, should be SPI_DATABIT_x, + where x is in range from 8 - 16 */ + uint32_t CPHA; /** Clock phase, should be: + - SPI_CPHA_FIRST: first clock edge + - SPI_CPHA_SECOND: second clock edge */ + uint32_t CPOL; /** Clock polarity, should be: + - SPI_CPOL_HI: high level + - SPI_CPOL_LO: low level */ + uint32_t Mode; /** SPI mode, should be: + - SPI_MASTER_MODE: Master mode + - SPI_SLAVE_MODE: Slave mode */ + uint32_t DataOrder; /** Data order, should be: + - SPI_DATA_MSB_FIRST: MSB first + - SPI_DATA_LSB_FIRST: LSB first */ + uint32_t ClockRate; /** Clock rate,in Hz, should not exceed + (SPI peripheral clock)/8 */ +} SPI_CFG_Type; + + +/** + * @brief SPI Transfer Type definitions + */ +typedef enum { + SPI_TRANSFER_POLLING = 0, /**< Polling transfer */ + SPI_TRANSFER_INTERRUPT /**< Interrupt transfer */ +} SPI_TRANSFER_Type; + +/** + * @brief SPI Data configuration structure definitions + */ +typedef struct { + void *tx_data; /**< Pointer to transmit data */ + void *rx_data; /**< Pointer to transmit data */ + uint32_t length; /**< Length of transfer data */ + uint32_t counter; /**< Data counter index */ + uint32_t status; /**< Current status of SPI activity */ +} SPI_DATA_SETUP_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup SPI_Public_Functions SPI Public Functions + * @{ + */ + +/* SPI Init/DeInit functions ---------*/ +void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct); +void SPI_DeInit(LPC_SPI_TypeDef *SPIx); +void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock); +void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct); + +/* SPI transfer functions ------------*/ +void SPI_SendData(LPC_SPI_TypeDef *SPIx, uint16_t Data); +uint16_t SPI_ReceiveData(LPC_SPI_TypeDef *SPIx); +int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, SPI_TRANSFER_Type xfType); + +/* SPI Interrupt functions ---------*/ +void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState); +IntStatus SPI_GetIntStatus (LPC_SPI_TypeDef *SPIx); +void SPI_ClearIntPending(LPC_SPI_TypeDef *SPIx); + +/* SPI get information functions-----*/ +uint8_t SPI_GetDataSize (LPC_SPI_TypeDef *SPIx); +uint32_t SPI_GetStatus(LPC_SPI_TypeDef *SPIx); +FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus, uint8_t SPIStatus); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_SPI_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_ssp.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_ssp.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,682 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup SSP + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_ssp.h" +#include "lpc17xx_clkpwr.h" + + +/* If this source file built with example, the LPC17xx FW library configuration + * file in each example directory ("lpc17xx_libcfg.h") must be included, + * otherwise the default FW library configuration file must be included instead + */ +#ifdef __BUILD_WITH_EXAMPLE__ +#include "lpc17xx_libcfg.h" +#else +#include "lpc17xx_libcfg_default.h" +#endif /* __BUILD_WITH_EXAMPLE__ */ + + +#ifdef _SSP + +/* 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 = 0; + uint8_t *wdata8 = 0; + uint16_t *rdata16 = 0; + uint16_t *wdata16 = 0; + uint32_t stat = 0; + uint32_t tmp = 0; + 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)>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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_ssp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_ssp.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,460 @@ +/***********************************************************************//** + * @file lpc17xx_ssp.h + * @brief Contains all macro definitions and function prototypes + * support for SSP firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup SSP SSP + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_SSP_H_ +#define LPC17XX_SSP_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup SSP_Public_Macros SSP Public Macros + * @{ + */ + +/*********************************************************************//** + * SSP configuration parameter defines + **********************************************************************/ +/** Clock phase control bit */ +#define SSP_CPHA_FIRST ((uint32_t)(0)) +#define SSP_CPHA_SECOND SSP_CR0_CPHA_SECOND + + +/** Clock polarity control bit */ +/* There's no bug here!!! + * - If bit[6] in SSPnCR0 is 0: SSP controller maintains the bus clock low between frames. + * That means the active clock is in HI state. + * - If bit[6] in SSPnCR0 is 1 (SSP_CR0_CPOL_HI): SSP controller maintains the bus clock + * high between frames. That means the active clock is in LO state. + */ +#define SSP_CPOL_HI ((uint32_t)(0)) +#define SSP_CPOL_LO SSP_CR0_CPOL_HI + +/** SSP master mode enable */ +#define SSP_SLAVE_MODE SSP_CR1_SLAVE_EN +#define SSP_MASTER_MODE ((uint32_t)(0)) + +/** SSP data bit number defines */ +#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */ +#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */ +#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */ +#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */ +#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */ +#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */ +#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */ +#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */ +#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */ +#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */ +#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */ +#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */ +#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */ + +/** SSP Frame Format definition */ +/** Motorola SPI mode */ +#define SSP_FRAME_SPI SSP_CR0_FRF_SPI +/** TI synchronous serial mode */ +#define SSP_FRAME_TI SSP_CR0_FRF_TI +/** National Micro-wire mode */ +#define SSP_FRAME_MICROWIRE SSP_CR0_FRF_MICROWIRE + +/*********************************************************************//** + * SSP Status defines + **********************************************************************/ +/** SSP status TX FIFO Empty bit */ +#define SSP_STAT_TXFIFO_EMPTY SSP_SR_TFE +/** SSP status TX FIFO not full bit */ +#define SSP_STAT_TXFIFO_NOTFULL SSP_SR_TNF +/** SSP status RX FIFO not empty bit */ +#define SSP_STAT_RXFIFO_NOTEMPTY SSP_SR_RNE +/** SSP status RX FIFO full bit */ +#define SSP_STAT_RXFIFO_FULL SSP_SR_RFF +/** SSP status SSP Busy bit */ +#define SSP_STAT_BUSY SSP_SR_BSY + +/*********************************************************************//** + * SSP Interrupt Configuration defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTCFG_ROR SSP_IMSC_ROR +/** Receive TimeOut */ +#define SSP_INTCFG_RT SSP_IMSC_RT +/** Rx FIFO is at least half full */ +#define SSP_INTCFG_RX SSP_IMSC_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTCFG_TX SSP_IMSC_TX + +/*********************************************************************//** + * SSP Configured Interrupt Status defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTSTAT_ROR SSP_MIS_ROR +/** Receive TimeOut */ +#define SSP_INTSTAT_RT SSP_MIS_RT +/** Rx FIFO is at least half full */ +#define SSP_INTSTAT_RX SSP_MIS_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTSTAT_TX SSP_MIS_TX + +/*********************************************************************//** + * SSP Raw Interrupt Status defines + **********************************************************************/ +/** Receive Overrun */ +#define SSP_INTSTAT_RAW_ROR SSP_RIS_ROR +/** Receive TimeOut */ +#define SSP_INTSTAT_RAW_RT SSP_RIS_RT +/** Rx FIFO is at least half full */ +#define SSP_INTSTAT_RAW_RX SSP_RIS_RX +/** Tx FIFO is at least half empty */ +#define SSP_INTSTAT_RAW_TX SSP_RIS_TX + +/*********************************************************************//** + * SSP Interrupt Clear defines + **********************************************************************/ +/** Writing a 1 to this bit clears the "frame was received when + * RxFIFO was full" interrupt */ +#define SSP_INTCLR_ROR SSP_ICR_ROR +/** Writing a 1 to this bit clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt */ +#define SSP_INTCLR_RT SSP_ICR_RT + +/*********************************************************************//** + * SSP DMA defines + **********************************************************************/ +/** SSP bit for enabling RX DMA */ +#define SSP_DMA_RX SSP_DMA_RXDMA_EN +/** SSP bit for enabling TX DMA */ +#define SSP_DMA_TX SSP_DMA_TXDMA_EN + +/* SSP Status Implementation definitions */ +#define SSP_STAT_DONE (1UL<<8) /**< Done */ +#define SSP_STAT_ERROR (1UL<<9) /**< Error */ + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup SSP_Private_Macros SSP Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for CR0 register + **********************************************************************/ +/** SSP data size select, must be 4 bits to 16 bits */ +#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF)) +/** SSP control 0 Motorola SPI mode */ +#define SSP_CR0_FRF_SPI ((uint32_t)(0<<4)) +/** SSP control 0 TI synchronous serial mode */ +#define SSP_CR0_FRF_TI ((uint32_t)(1<<4)) +/** SSP control 0 National Micro-wire mode */ +#define SSP_CR0_FRF_MICROWIRE ((uint32_t)(2<<4)) +/** SPI clock polarity bit (used in SPI mode only), (1) = maintains the + bus clock high between frames, (0) = low */ +#define SSP_CR0_CPOL_HI ((uint32_t)(1<<6)) +/** SPI clock out phase bit (used in SPI mode only), (1) = captures data + on the second clock transition of the frame, (0) = first */ +#define SSP_CR0_CPHA_SECOND ((uint32_t)(1<<7)) +/** SSP serial clock rate value load macro, divider rate is + PERIPH_CLK / (cpsr * (SCR + 1)) */ +#define SSP_CR0_SCR(n) ((uint32_t)((n&0xFF)<<8)) +/** SSP CR0 bit mask */ +#define SSP_CR0_BITMASK ((uint32_t)(0xFFFF)) + +/*********************************************************************//** + * Macro defines for CR1 register + **********************************************************************/ +/** SSP control 1 loopback mode enable bit */ +#define SSP_CR1_LBM_EN ((uint32_t)(1<<0)) +/** SSP control 1 enable bit */ +#define SSP_CR1_SSP_EN ((uint32_t)(1<<1)) +/** SSP control 1 slave enable */ +#define SSP_CR1_SLAVE_EN ((uint32_t)(1<<2)) +/** SSP control 1 slave out disable bit, disables transmit line in slave + mode */ +#define SSP_CR1_SO_DISABLE ((uint32_t)(1<<3)) +/** SSP CR1 bit mask */ +#define SSP_CR1_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro defines for DR register + **********************************************************************/ +/** SSP data bit mask */ +#define SSP_DR_BITMASK(n) ((n)&0xFFFF) + +/*********************************************************************//** + * Macro defines for SR register + **********************************************************************/ +/** SSP status TX FIFO Empty bit */ +#define SSP_SR_TFE ((uint32_t)(1<<0)) +/** SSP status TX FIFO not full bit */ +#define SSP_SR_TNF ((uint32_t)(1<<1)) +/** SSP status RX FIFO not empty bit */ +#define SSP_SR_RNE ((uint32_t)(1<<2)) +/** SSP status RX FIFO full bit */ +#define SSP_SR_RFF ((uint32_t)(1<<3)) +/** SSP status SSP Busy bit */ +#define SSP_SR_BSY ((uint32_t)(1<<4)) +/** SSP SR bit mask */ +#define SSP_SR_BITMASK ((uint32_t)(0x1F)) + +/*********************************************************************//** + * Macro defines for CPSR register + **********************************************************************/ +/** SSP clock prescaler */ +#define SSP_CPSR_CPDVSR(n) ((uint32_t)(n&0xFF)) +/** SSP CPSR bit mask */ +#define SSP_CPSR_BITMASK ((uint32_t)(0xFF)) + +/*********************************************************************//** + * Macro define for (IMSC) Interrupt Mask Set/Clear registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_IMSC_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_IMSC_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_IMSC_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_IMSC_TX ((uint32_t)(1<<3)) +/** IMSC bit mask */ +#define SSP_IMSC_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (RIS) Raw Interrupt Status registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_RIS_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_RIS_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_RIS_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_RIS_TX ((uint32_t)(1<<3)) +/** RIS bit mask */ +#define SSP_RIS_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (MIS) Masked Interrupt Status registers + **********************************************************************/ +/** Receive Overrun */ +#define SSP_MIS_ROR ((uint32_t)(1<<0)) +/** Receive TimeOut */ +#define SSP_MIS_RT ((uint32_t)(1<<1)) +/** Rx FIFO is at least half full */ +#define SSP_MIS_RX ((uint32_t)(1<<2)) +/** Tx FIFO is at least half empty */ +#define SSP_MIS_TX ((uint32_t)(1<<3)) +/** MIS bit mask */ +#define SSP_MIS_BITMASK ((uint32_t)(0x0F)) + +/*********************************************************************//** + * Macro define for (ICR) Interrupt Clear registers + **********************************************************************/ +/** Writing a 1 to this bit clears the "frame was received when + * RxFIFO was full" interrupt */ +#define SSP_ICR_ROR ((uint32_t)(1<<0)) +/** Writing a 1 to this bit clears the "Rx FIFO was not empty and + * has not been read for a timeout period" interrupt */ +#define SSP_ICR_RT ((uint32_t)(1<<1)) +/** ICR bit mask */ +#define SSP_ICR_BITMASK ((uint32_t)(0x03)) + +/*********************************************************************//** + * Macro defines for DMACR register + **********************************************************************/ +/** SSP bit for enabling RX DMA */ +#define SSP_DMA_RXDMA_EN ((uint32_t)(1<<0)) +/** SSP bit for enabling TX DMA */ +#define SSP_DMA_TXDMA_EN ((uint32_t)(1<<1)) +/** DMACR bit mask */ +#define SSP_DMA_BITMASK ((uint32_t)(0x03)) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid SSP port number */ +#define PARAM_SSPx(n) ((((uint32_t *)n)==((uint32_t *)LPC_SSP0)) \ +|| (((uint32_t *)n)==((uint32_t *)LPC_SSP1))) + +/** Macro check clock phase control mode */ +#define PARAM_SSP_CPHA(n) ((n==SSP_CPHA_FIRST) || (n==SSP_CPHA_SECOND)) + +/** Macro check clock polarity mode */ +#define PARAM_SSP_CPOL(n) ((n==SSP_CPOL_HI) || (n==SSP_CPOL_LO)) + +/* Macro check master/slave mode */ +#define PARAM_SSP_MODE(n) ((n==SSP_SLAVE_MODE) || (n==SSP_MASTER_MODE)) + +/* Macro check databit value */ +#define PARAM_SSP_DATABIT(n) ((n==SSP_DATABIT_4) || (n==SSP_DATABIT_5) \ +|| (n==SSP_DATABIT_6) || (n==SSP_DATABIT_16) \ +|| (n==SSP_DATABIT_7) || (n==SSP_DATABIT_8) \ +|| (n==SSP_DATABIT_9) || (n==SSP_DATABIT_10) \ +|| (n==SSP_DATABIT_11) || (n==SSP_DATABIT_12) \ +|| (n==SSP_DATABIT_13) || (n==SSP_DATABIT_14) \ +|| (n==SSP_DATABIT_15)) + +/* Macro check frame type */ +#define PARAM_SSP_FRAME(n) ((n==SSP_FRAME_SPI) || (n==SSP_FRAME_TI)\ +|| (n==SSP_FRAME_MICROWIRE)) + +/* Macro check SSP status */ +#define PARAM_SSP_STAT(n) ((n==SSP_STAT_TXFIFO_EMPTY) || (n==SSP_STAT_TXFIFO_NOTFULL) \ +|| (n==SSP_STAT_RXFIFO_NOTEMPTY) || (n==SSP_STAT_RXFIFO_FULL) \ +|| (n==SSP_STAT_BUSY)) + +/* Macro check interrupt configuration */ +#define PARAM_SSP_INTCFG(n) ((n==SSP_INTCFG_ROR) || (n==SSP_INTCFG_RT) \ +|| (n==SSP_INTCFG_RX) || (n==SSP_INTCFG_TX)) + +/* Macro check interrupt status value */ +#define PARAM_SSP_INTSTAT(n) ((n==SSP_INTSTAT_ROR) || (n==SSP_INTSTAT_RT) \ +|| (n==SSP_INTSTAT_RX) || (n==SSP_INTSTAT_TX)) + +/* Macro check interrupt status raw value */ +#define PARAM_SSP_INTSTAT_RAW(n) ((n==SSP_INTSTAT_RAW_ROR) || (n==SSP_INTSTAT_RAW_RT) \ +|| (n==SSP_INTSTAT_RAW_RX) || (n==SSP_INTSTAT_RAW_TX)) + +/* Macro check interrupt clear mode */ +#define PARAM_SSP_INTCLR(n) ((n==SSP_INTCLR_ROR) || (n==SSP_INTCLR_RT)) + +/* Macro check DMA mode */ +#define PARAM_SSP_DMA(n) ((n==SSP_DMA_TX) || (n==SSP_DMA_RX)) +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup SSP_Public_Types SSP Public Types + * @{ + */ + +/** @brief SSP configuration structure */ +typedef struct { + uint32_t Databit; /** Databit number, should be SSP_DATABIT_x, + where x is in range from 4 - 16 */ + uint32_t CPHA; /** Clock phase, should be: + - SSP_CPHA_FIRST: first clock edge + - SSP_CPHA_SECOND: second clock edge */ + uint32_t CPOL; /** Clock polarity, should be: + - SSP_CPOL_HI: high level + - SSP_CPOL_LO: low level */ + uint32_t Mode; /** SSP mode, should be: + - SSP_MASTER_MODE: Master mode + - SSP_SLAVE_MODE: Slave mode */ + uint32_t FrameFormat; /** Frame Format: + - SSP_FRAME_SPI: Motorola SPI frame format + - SSP_FRAME_TI: TI frame format + - SSP_FRAME_MICROWIRE: National Microwire frame format */ + uint32_t ClockRate; /** Clock rate,in Hz */ +} SSP_CFG_Type; + +/** + * @brief SSP Transfer Type definitions + */ +typedef enum { + SSP_TRANSFER_POLLING = 0, /**< Polling transfer */ + SSP_TRANSFER_INTERRUPT /**< Interrupt transfer */ +} SSP_TRANSFER_Type; + +/** + * @brief SPI Data configuration structure definitions + */ +typedef struct { + void *tx_data; /**< Pointer to transmit data */ + uint32_t tx_cnt; /**< Transmit counter */ + void *rx_data; /**< Pointer to transmit data */ + uint32_t rx_cnt; /**< Receive counter */ + uint32_t length; /**< Length of transfer data */ + uint32_t status; /**< Current status of SSP activity */ +} SSP_DATA_SETUP_Type; + + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup SSP_Public_Functions SSP Public Functions + * @{ + */ + +/* SSP Init/DeInit functions --------------------------------------------------*/ +void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct); +void SSP_DeInit(LPC_SSP_TypeDef* SSPx); + +/* SSP configure functions ----------------------------------------------------*/ +void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct); + +/* SSP enable/disable functions -----------------------------------------------*/ +void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState); +void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState); + +/* SSP get information functions ----------------------------------------------*/ +FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType); +uint8_t SSP_GetDataSize(LPC_SSP_TypeDef* SSPx); +IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType); +uint32_t SSP_GetRawIntStatusReg(LPC_SSP_TypeDef *SSPx); +IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType); + +/* SSP transfer data functions ------------------------------------------------*/ +void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data); +uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx); +int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \ + SSP_TRANSFER_Type xfType); + +/* SSP IRQ function ------------------------------------------------------------*/ +void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState); +void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_SSP_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_systick.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_systick.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,180 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 LOAD 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 ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_systick.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_systick.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,107 @@ +/***********************************************************************//** + * @file lpc17xx_systick.h + * @brief Contains all macro definitions and function prototypes + * support for SYSTICK firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup SYSTICK SYSTICK + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_SYSTICK_H_ +#define LPC17XX_SYSTICK_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup SYSTICK_Private_Macros SYSTICK Private Macros + * @{ + */ +/*********************************************************************//** + * Macro defines for System Timer Control and status (STCTRL) register + **********************************************************************/ +#define ST_CTRL_ENABLE ((uint32_t)(1<<0)) +#define ST_CTRL_TICKINT ((uint32_t)(1<<1)) +#define ST_CTRL_CLKSOURCE ((uint32_t)(1<<2)) +#define ST_CTRL_COUNTFLAG ((uint32_t)(1<<16)) + +/*********************************************************************//** + * Macro defines for System Timer Reload value (STRELOAD) register + **********************************************************************/ +#define ST_RELOAD_RELOAD(n) ((uint32_t)(n & 0x00FFFFFF)) + +/*********************************************************************//** + * Macro defines for System Timer Current value (STCURRENT) register + **********************************************************************/ +#define ST_RELOAD_CURRENT(n) ((uint32_t)(n & 0x00FFFFFF)) + +/*********************************************************************//** + * Macro defines for System Timer Calibration value (STCALIB) register + **********************************************************************/ +#define ST_CALIB_TENMS(n) ((uint32_t)(n & 0x00FFFFFF)) +#define ST_CALIB_SKEW ((uint32_t)(1<<30)) +#define ST_CALIB_NOREF ((uint32_t)(1<<31)) + +#define CLKSOURCE_EXT ((uint32_t)(0)) +#define CLKSOURCE_CPU ((uint32_t)(1)) + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup SYSTICK_Public_Functions SYSTICK Public Functions + * @{ + */ + +void SYSTICK_InternalInit(uint32_t time); +void SYSTICK_ExternalInit(uint32_t freq, uint32_t time); + +void SYSTICK_Cmd(FunctionalState NewState); +void SYSTICK_IntCmd(FunctionalState NewState); +uint32_t SYSTICK_GetCurrentValue(void); +void SYSTICK_ClearCounterFlag(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LPC17XX_SYSTICK_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_timer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_timer.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,591 @@ +/***********************************************************************//** + * @file lpc17xx_timer.c + * @brief Contains all functions support for Timer firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = 0; + 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 -1 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); + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER0, CLKPWR_PCLKSEL_CCLK_DIV_4); + } + else if (TIMx== LPC_TIM1) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM1, ENABLE); + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER1, CLKPWR_PCLKSEL_CCLK_DIV_4); + + } + + else if (TIMx== LPC_TIM2) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM2, ENABLE); + CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_TIMER2, CLKPWR_PCLKSEL_CCLK_DIV_4); + } + else if (TIMx== LPC_TIM3) + { + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCTIM3, ENABLE); + 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_timer.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,335 @@ +/***********************************************************************//** + * @file lpc17xx_timer.h + * @brief Contains all functions support for Timer firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup TIM TIM + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC17XX_TIMER_H_ +#define __LPC17XX_TIMER_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/********************************************************************** +** Interrupt information +**********************************************************************/ +/** Macro to clean interrupt pending */ +#define TIM_IR_CLR(n) _BIT(n) + +/********************************************************************** +** Timer interrupt register definitions +**********************************************************************/ +/** Macro for getting a timer match interrupt bit */ +#define TIM_MATCH_INT(n) (_BIT(n & 0x0F)) +/** Macro for getting a capture event interrupt bit */ +#define TIM_CAP_INT(n) (_BIT(((n & 0x0F) + 4))) + +/********************************************************************** +* Timer control register definitions +**********************************************************************/ +/** Timer/counter enable bit */ +#define TIM_ENABLE ((uint32_t)(1<<0)) +/** Timer/counter reset bit */ +#define TIM_RESET ((uint32_t)(1<<1)) +/** Timer control bit mask */ +#define TIM_TCR_MASKBIT ((uint32_t)(3)) + +/********************************************************************** +* Timer match control register definitions +**********************************************************************/ +/** Bit location for interrupt on MRx match, n = 0 to 3 */ +#define TIM_INT_ON_MATCH(n) (_BIT((n * 3))) +/** Bit location for reset on MRx match, n = 0 to 3 */ +#define TIM_RESET_ON_MATCH(n) (_BIT(((n * 3) + 1))) +/** Bit location for stop on MRx match, n = 0 to 3 */ +#define TIM_STOP_ON_MATCH(n) (_BIT(((n * 3) + 2))) +/** Timer Match control bit mask */ +#define TIM_MCR_MASKBIT ((uint32_t)(0x0FFF)) +/** Timer Match control bit mask for specific channel*/ +#define TIM_MCR_CHANNEL_MASKBIT(n) ((uint32_t)(7<<(n*3))) + +/********************************************************************** +* Timer capture control register definitions +**********************************************************************/ +/** Bit location for CAP.n on CRx rising edge, n = 0 to 3 */ +#define TIM_CAP_RISING(n) (_BIT((n * 3))) +/** Bit location for CAP.n on CRx falling edge, n = 0 to 3 */ +#define TIM_CAP_FALLING(n) (_BIT(((n * 3) + 1))) +/** Bit location for CAP.n on CRx interrupt enable, n = 0 to 3 */ +#define TIM_INT_ON_CAP(n) (_BIT(((n * 3) + 2))) +/** Mask bit for rising and falling edge bit */ +#define TIM_EDGE_MASK(n) (_SBF((n * 3), 0x03)) +/** Timer capture control bit mask */ +#define TIM_CCR_MASKBIT ((uint32_t)(0x3F)) +/** Timer Capture control bit mask for specific channel*/ +#define TIM_CCR_CHANNEL_MASKBIT(n) ((uint32_t)(7<<(n*3))) + +/********************************************************************** +* Timer external match register definitions +**********************************************************************/ +/** Bit location for output state change of MAT.n when external match + happens, n = 0 to 3 */ +#define TIM_EM(n) _BIT(n) +/** Output state change of MAT.n when external match happens: no change */ +#define TIM_EM_NOTHING ((uint8_t)(0x0)) +/** Output state change of MAT.n when external match happens: low */ +#define TIM_EM_LOW ((uint8_t)(0x1)) +/** Output state change of MAT.n when external match happens: high */ +#define TIM_EM_HIGH ((uint8_t)(0x2)) +/** Output state change of MAT.n when external match happens: toggle */ +#define TIM_EM_TOGGLE ((uint8_t)(0x3)) +/** Macro for setting for the MAT.n change state bits */ +#define TIM_EM_SET(n,s) (_SBF(((n << 1) + 4), (s & 0x03))) +/** Mask for the MAT.n change state bits */ +#define TIM_EM_MASK(n) (_SBF(((n << 1) + 4), 0x03)) +/** Timer external match bit mask */ +#define TIM_EMR_MASKBIT 0x0FFF + +/********************************************************************** +* Timer Count Control Register definitions +**********************************************************************/ +/** Mask to get the Counter/timer mode bits */ +#define TIM_CTCR_MODE_MASK 0x3 +/** Mask to get the count input select bits */ +#define TIM_CTCR_INPUT_MASK 0xC +/** Timer Count control bit mask */ +#define TIM_CTCR_MASKBIT 0xF +#define TIM_COUNTER_MODE ((uint8_t)(1)) + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/** Macro to determine if it is valid TIMER peripheral */ +#define PARAM_TIMx(n) ((((uint32_t *)n)==((uint32_t *)LPC_TIM0)) || (((uint32_t *)n)==((uint32_t *)LPC_TIM1)) \ +|| (((uint32_t *)n)==((uint32_t *)LPC_TIM2)) || (((uint32_t *)n)==((uint32_t *)LPC_TIM3))) + +/* Macro check interrupt type */ +#define PARAM_TIM_INT_TYPE(TYPE) ((TYPE ==TIM_MR0_INT)||(TYPE ==TIM_MR1_INT)\ +||(TYPE ==TIM_MR2_INT)||(TYPE ==TIM_MR3_INT)\ +||(TYPE ==TIM_CR0_INT)||(TYPE ==TIM_CR1_INT)) + +/* Macro check TIMER mode */ +#define PARAM_TIM_MODE_OPT(MODE) ((MODE == TIM_TIMER_MODE)||(MODE == TIM_COUNTER_RISING_MODE)\ +|| (MODE == TIM_COUNTER_RISING_MODE)||(MODE == TIM_COUNTER_RISING_MODE)) + +/* Macro check TIMER prescale value */ +#define PARAM_TIM_PRESCALE_OPT(OPT) ((OPT == TIM_PRESCALE_TICKVAL)||(OPT == TIM_PRESCALE_USVAL)) + +/* Macro check TIMER counter intput mode */ +#define PARAM_TIM_COUNTER_INPUT_OPT(OPT) ((OPT == TIM_COUNTER_INCAP0)||(OPT == TIM_COUNTER_INCAP1)) + +/* Macro check TIMER external match mode */ +#define PARAM_TIM_EXTMATCH_OPT(OPT) ((OPT == TIM_EXTMATCH_NOTHING)||(OPT == TIM_EXTMATCH_LOW)\ +||(OPT == TIM_EXTMATCH_HIGH)||(OPT == TIM_EXTMATCH_TOGGLE)) + +/* Macro check TIMER external match mode */ +#define PARAM_TIM_CAP_MODE_OPT(OPT) ((OPT == TIM_CAPTURE_NONE)||(OPT == TIM_CAPTURE_RISING) \ +||(OPT == TIM_CAPTURE_FALLING)||(OPT == TIM_CAPTURE_ANY)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup TIM_Public_Types TIM Public Types + * @{ + */ + +/*********************************************************************** + * Timer device enumeration +**********************************************************************/ +/** @brief interrupt type */ +typedef enum +{ + TIM_MR0_INT =0, /*!< interrupt for Match channel 0*/ + TIM_MR1_INT =1, /*!< interrupt for Match channel 1*/ + TIM_MR2_INT =2, /*!< interrupt for Match channel 2*/ + TIM_MR3_INT =3, /*!< interrupt for Match channel 3*/ + TIM_CR0_INT =4, /*!< interrupt for Capture channel 0*/ + TIM_CR1_INT =5, /*!< interrupt for Capture channel 1*/ +}TIM_INT_TYPE; + +/** @brief Timer/counter operating mode */ +typedef enum +{ + TIM_TIMER_MODE = 0, /*!< Timer mode */ + TIM_COUNTER_RISING_MODE, /*!< Counter rising mode */ + TIM_COUNTER_FALLING_MODE, /*!< Counter falling mode */ + TIM_COUNTER_ANY_MODE /*!< Counter on both edges */ +} TIM_MODE_OPT; + +/** @brief Timer/Counter prescale option */ +typedef enum +{ + TIM_PRESCALE_TICKVAL = 0, /*!< Prescale in absolute value */ + TIM_PRESCALE_USVAL /*!< Prescale in microsecond value */ +} TIM_PRESCALE_OPT; + +/** @brief Counter input option */ +typedef enum +{ + TIM_COUNTER_INCAP0 = 0, /*!< CAPn.0 input pin for TIMERn */ + TIM_COUNTER_INCAP1, /*!< CAPn.1 input pin for TIMERn */ +} TIM_COUNTER_INPUT_OPT; + +/** @brief Timer/Counter external match option */ +typedef enum +{ + TIM_EXTMATCH_NOTHING = 0, /*!< Do nothing for external output pin if match */ + TIM_EXTMATCH_LOW, /*!< Force external output pin to low if match */ + TIM_EXTMATCH_HIGH, /*!< Force external output pin to high if match */ + TIM_EXTMATCH_TOGGLE /*!< Toggle external output pin if match */ +}TIM_EXTMATCH_OPT; + +/** @brief Timer/counter capture mode options */ +typedef enum { + TIM_CAPTURE_NONE = 0, /*!< No Capture */ + TIM_CAPTURE_RISING, /*!< Rising capture mode */ + TIM_CAPTURE_FALLING, /*!< Falling capture mode */ + TIM_CAPTURE_ANY /*!< On both edges */ +} TIM_CAP_MODE_OPT; + +/** @brief Configuration structure in TIMER mode */ +typedef struct +{ + + uint8_t PrescaleOption; /**< Timer Prescale option, should be: + - TIM_PRESCALE_TICKVAL: Prescale in absolute value + - TIM_PRESCALE_USVAL: Prescale in microsecond value + */ + uint8_t Reserved[3]; /**< Reserved */ + uint32_t PrescaleValue; /**< Prescale value */ +} TIM_TIMERCFG_Type; + +/** @brief Configuration structure in COUNTER mode */ +typedef struct { + + uint8_t CounterOption; /**< Counter Option, should be: + - TIM_COUNTER_INCAP0: CAPn.0 input pin for TIMERn + - TIM_COUNTER_INCAP1: CAPn.1 input pin for TIMERn + */ + uint8_t CountInputSelect; + uint8_t Reserved[2]; +} TIM_COUNTERCFG_Type; + +/** @brief Match channel configuration structure */ +typedef struct { + uint8_t MatchChannel; /**< Match channel, should be in range + from 0..3 */ + uint8_t IntOnMatch; /**< Interrupt On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t StopOnMatch; /**< Stop On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + uint8_t ResetOnMatch; /**< Reset On match, should be: + - ENABLE: Enable this function. + - DISABLE: Disable this function. + */ + + uint8_t ExtMatchOutputType; /**< External Match Output type, should be: + - TIM_EXTMATCH_NOTHING: Do nothing for external output pin if match + - TIM_EXTMATCH_LOW: Force external output pin to low if match + - TIM_EXTMATCH_HIGH: Force external output pin to high if match + - TIM_EXTMATCH_TOGGLE: Toggle external output pin if match. + */ + uint8_t Reserved[3]; /** Reserved */ + uint32_t MatchValue; /** Match value */ +} TIM_MATCHCFG_Type; + +/** @brief Capture Input configuration structure */ +typedef struct { + uint8_t CaptureChannel; /**< Capture channel, should be in range + from 0..1 */ + uint8_t RisingEdge; /**< caption rising edge, should be: + - ENABLE: Enable rising edge. + - DISABLE: Disable this function. + */ + uint8_t FallingEdge; /**< caption falling edge, should be: + - ENABLE: Enable falling edge. + - DISABLE: Disable this function. + */ + uint8_t IntOnCaption; /**< Interrupt On caption, should be: + - ENABLE: Enable interrupt function. + - DISABLE: Disable this function. + */ + +} TIM_CAPTURECFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup TIM_Public_Functions TIM Public Functions + * @{ + */ +/* Init/DeInit TIM functions -----------*/ +void TIM_Init(LPC_TIM_TypeDef *TIMx, TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct); +void TIM_DeInit(LPC_TIM_TypeDef *TIMx); + +/* TIM interrupt functions -------------*/ +void TIM_ClearIntPending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +void TIM_ClearIntCapturePending(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +FlagStatus TIM_GetIntStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); +FlagStatus TIM_GetIntCaptureStatus(LPC_TIM_TypeDef *TIMx, TIM_INT_TYPE IntFlag); + +/* TIM configuration functions --------*/ +void TIM_ConfigStructInit(TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct); +void TIM_ConfigMatch(LPC_TIM_TypeDef *TIMx, TIM_MATCHCFG_Type *TIM_MatchConfigStruct); +void TIM_UpdateMatchValue(LPC_TIM_TypeDef *TIMx,uint8_t MatchChannel, uint32_t MatchValue); +void TIM_SetMatchExt(LPC_TIM_TypeDef *TIMx,TIM_EXTMATCH_OPT ext_match ); +void TIM_ConfigCapture(LPC_TIM_TypeDef *TIMx, TIM_CAPTURECFG_Type *TIM_CaptureConfigStruct); +void TIM_Cmd(LPC_TIM_TypeDef *TIMx, FunctionalState NewState); + +uint32_t TIM_GetCaptureValue(LPC_TIM_TypeDef *TIMx, TIM_COUNTER_INPUT_OPT CaptureChannel); +void TIM_ResetCounter(LPC_TIM_TypeDef *TIMx); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __LPC17XX_TIMER_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_uart.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_uart.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,1366 @@ +/***********************************************************************//** + * @file lpc17xx_uart.c + * @brief Contains all functions support for UART firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup UART + * @{ + */ + +/* Includes ------------------------------------------------------------------- */ +#include "lpc17xx_uart.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 _UART + +/* Private Functions ---------------------------------------------------------- */ + +static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate); + + +/*********************************************************************//** + * @brief Determines best dividers to get a target clock rate + * @param[in] UARTx Pointer to selected UART peripheral, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] baudrate Desired UART baud rate. + * @return Error status, could be: + * - SUCCESS + * - ERROR + **********************************************************************/ +static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate) +{ + Status errorStatus = ERROR; + + uint32_t uClk = 0; + uint32_t calcBaudrate = 0; + uint32_t temp = 0; + + uint32_t mulFracDiv, dividerAddFracDiv; + uint32_t diviser = 0 ; + uint32_t mulFracDivOptimal = 1; + uint32_t dividerAddOptimal = 0; + uint32_t diviserOptimal = 0; + + uint32_t relativeError = 0; + uint32_t relativeOptimalError = 100000; + + /* get UART block clock */ + if (UARTx == (LPC_UART_TypeDef *)LPC_UART0) + { + uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0); + } + else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1) + { + uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1); + } + else if (UARTx == (LPC_UART_TypeDef *)LPC_UART2) + { + uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2); + } + else if (UARTx == (LPC_UART_TypeDef *)LPC_UART3) + { + uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3); + } + + + uClk = uClk >> 4; /* div by 16 */ + /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers + * The formula is : + * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL) + * It involves floating point calculations. That's the reason the formulae are adjusted with + * Multiply and divide method.*/ + /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions: + * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */ + for (mulFracDiv = 1 ; mulFracDiv <= 15 ;mulFracDiv++) + { + for (dividerAddFracDiv = 0 ; dividerAddFracDiv <= 15 ;dividerAddFracDiv++) + { + temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv)); + + diviser = temp / baudrate; + if ((temp % baudrate) > (baudrate / 2)) + diviser++; + + if (diviser > 2 && diviser < 65536) + { + calcBaudrate = temp / diviser; + + if (calcBaudrate <= baudrate) + relativeError = baudrate - calcBaudrate; + else + relativeError = calcBaudrate - baudrate; + + if ((relativeError < relativeOptimalError)) + { + mulFracDivOptimal = mulFracDiv ; + dividerAddOptimal = dividerAddFracDiv; + diviserOptimal = diviser; + relativeOptimalError = relativeError; + if (relativeError == 0) + break; + } + } /* End of if */ + } /* end of inner for loop */ + if (relativeError == 0) + break; + } /* end of outer for loop */ + + if (relativeOptimalError < ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR)/100)) + { + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN; + ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal); + ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal); + /* Then reset DLAB bit */ + ((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; + ((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \ + | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK; + } + else + { + UARTx->LCR |= UART_LCR_DLAB_EN; + UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal); + UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal); + /* Then reset DLAB bit */ + UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK; + UARTx->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \ + | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK; + } + errorStatus = SUCCESS; + } + + return errorStatus; +} + +/* End of Private Functions ---------------------------------------------------- */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @addtogroup UART_Public_Functions + * @{ + */ +/* UART Init/DeInit functions -------------------------------------------------*/ +/********************************************************************//** + * @brief Initializes the UARTx peripheral according to the specified + * parameters in the UART_ConfigStruct. + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] UART_ConfigStruct Pointer to a UART_CFG_Type structure +* that contains the configuration information for the +* specified UART peripheral. + * @return None + *********************************************************************/ +void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct) +{ + uint32_t tmp; + + // For debug mode + CHECK_PARAM(PARAM_UARTx(UARTx)); + CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits)); + CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits)); + CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity)); + +#ifdef _UART0 + if(UARTx == (LPC_UART_TypeDef *)LPC_UART0) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE); + } +#endif + +#ifdef _UART1 + if(((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE); + } +#endif + +#ifdef _UART2 + if(UARTx == (LPC_UART_TypeDef *)LPC_UART2) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE); + } +#endif + +#ifdef _UART3 + if(UARTx == (LPC_UART_TypeDef *)LPC_UART3) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE); + } +#endif + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + /* FIFOs are empty */ + ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \ + | UART_FCR_RX_RS | UART_FCR_TX_RS); + // Disable FIFO + ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0; + + // Dummy reading + while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR) + { + tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR; + } + + ((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN; + // Wait for current transmit complete + while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE)); + // Disable Tx + ((LPC_UART1_TypeDef *)UARTx)->TER = 0; + + // Disable interrupt + ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0; + // Set LCR to default state + ((LPC_UART1_TypeDef *)UARTx)->LCR = 0; + // Set ACR to default state + ((LPC_UART1_TypeDef *)UARTx)->ACR = 0; + // Set Modem Control to default state + ((LPC_UART1_TypeDef *)UARTx)->MCR = 0; + // Set RS485 control to default state + ((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0; + // Set RS485 delay timer to default state + ((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0; + // Set RS485 addr match to default state + ((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0; + //Dummy Reading to Clear Status + tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR; + tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR; + } + else + { + /* FIFOs are empty */ + UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS); + // Disable FIFO + UARTx->/*IIFCR.*/FCR = 0; + + // Dummy reading + while (UARTx->LSR & UART_LSR_RDR) + { + tmp = UARTx->/*RBTHDLR.*/RBR; + } + + UARTx->TER = UART_TER_TXEN; + // Wait for current transmit complete + while (!(UARTx->LSR & UART_LSR_THRE)); + // Disable Tx + UARTx->TER = 0; + + // Disable interrupt + UARTx->/*DLIER.*/IER = 0; + // Set LCR to default state + UARTx->LCR = 0; + // Set ACR to default state + UARTx->ACR = 0; + // Dummy reading + tmp = UARTx->LSR; + } + + if (UARTx == LPC_UART3) + { + // Set IrDA to default state + UARTx->ICR = 0; + } + + // Set Line Control register ---------------------------- + + uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate)); + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \ + & UART_LCR_BITMASK; + } + else + { + tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK; + } + + switch (UART_ConfigStruct->Databits){ + case UART_DATABIT_5: + tmp |= UART_LCR_WLEN5; + break; + case UART_DATABIT_6: + tmp |= UART_LCR_WLEN6; + break; + case UART_DATABIT_7: + tmp |= UART_LCR_WLEN7; + break; + case UART_DATABIT_8: + default: + tmp |= UART_LCR_WLEN8; + break; + } + + if (UART_ConfigStruct->Parity == UART_PARITY_NONE) + { + // Do nothing... + } + else + { + tmp |= UART_LCR_PARITY_EN; + switch (UART_ConfigStruct->Parity) + { + case UART_PARITY_ODD: + tmp |= UART_LCR_PARITY_ODD; + break; + + case UART_PARITY_EVEN: + tmp |= UART_LCR_PARITY_EVEN; + break; + + case UART_PARITY_SP_1: + tmp |= UART_LCR_PARITY_F_1; + break; + + case UART_PARITY_SP_0: + tmp |= UART_LCR_PARITY_F_0; + break; + default: + break; + } + } + + switch (UART_ConfigStruct->Stopbits){ + case UART_STOPBIT_2: + tmp |= UART_LCR_STOPBIT_SEL; + break; + case UART_STOPBIT_1: + default: + // Do no thing + break; + } + + + // Write back to LCR, configure FIFO and Disable Tx + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); + } + else + { + UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK); + } +} + +/*********************************************************************//** + * @brief De-initializes the UARTx peripheral registers to their + * default reset values. + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return None + **********************************************************************/ +void UART_DeInit(LPC_UART_TypeDef* UARTx) +{ + // For debug mode + CHECK_PARAM(PARAM_UARTx(UARTx)); + + UART_TxCmd(UARTx, DISABLE); + +#ifdef _UART0 + if (UARTx == (LPC_UART_TypeDef *)LPC_UART0) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE); + } +#endif + +#ifdef _UART1 + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE); + } +#endif + +#ifdef _UART2 + if (UARTx == (LPC_UART_TypeDef *)LPC_UART2) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE); + } +#endif + +#ifdef _UART3 + if (UARTx == (LPC_UART_TypeDef *)LPC_UART3) + { + /* Set up clock and power for UART module */ + CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE); + } +#endif +} + +/*****************************************************************************//** +* @brief Fills each UART_InitStruct member with its default value: +* - 9600 bps +* - 8-bit data +* - 1 Stopbit +* - None Parity +* @param[in] UART_InitStruct Pointer to a UART_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct) +{ + UART_InitStruct->Baud_rate = 9600; + UART_InitStruct->Databits = UART_DATABIT_8; + UART_InitStruct->Parity = UART_PARITY_NONE; + UART_InitStruct->Stopbits = UART_STOPBIT_1; +} + +/* UART Send/Recieve functions -------------------------------------------------*/ +/*********************************************************************//** + * @brief Transmit a single data through UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] Data Data to transmit (must be 8-bit long) + * @return None + **********************************************************************/ +void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT; + } + else + { + UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT; + } + +} + + +/*********************************************************************//** + * @brief Receive a single data from UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return Data received + **********************************************************************/ +uint8_t UART_ReceiveByte(LPC_UART_TypeDef* UARTx) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT); + } + else + { + return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT); + } +} + +/*********************************************************************//** + * @brief Send a block of data via UART peripheral + * @param[in] UARTx Selected UART peripheral used to send data, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] txbuf Pointer to Transmit buffer + * @param[in] buflen Length of Transmit buffer + * @param[in] flag Flag used in UART transfer, should be + * NONE_BLOCKING or BLOCKING + * @return Number of bytes sent. + * + * Note: when using UART in BLOCKING mode, a time-out condition is used + * via defined symbol UART_BLOCKING_TIMEOUT. + **********************************************************************/ +uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf, + uint32_t buflen, TRANSFER_BLOCK_Type flag) +{ + uint32_t bToSend, bSent, timeOut, fifo_cnt; + uint8_t *pChar = txbuf; + + bToSend = buflen; + + // blocking mode + if (flag == BLOCKING) { + bSent = 0; + while (bToSend){ + timeOut = UART_BLOCKING_TIMEOUT; + // Wait for THR empty with timeout + while (!(UARTx->LSR & UART_LSR_THRE)) { + if (timeOut == 0) break; + timeOut--; + } + // Time out! + if(timeOut == 0) break; + fifo_cnt = UART_TX_FIFO_SIZE; + while (fifo_cnt && bToSend){ + UART_SendByte(UARTx, (*pChar++)); + fifo_cnt--; + bToSend--; + bSent++; + } + } + } + // None blocking mode + else { + bSent = 0; + while (bToSend) { + if (!(UARTx->LSR & UART_LSR_THRE)){ + break; + } + fifo_cnt = UART_TX_FIFO_SIZE; + while (fifo_cnt && bToSend) { + UART_SendByte(UARTx, (*pChar++)); + bToSend--; + fifo_cnt--; + bSent++; + } + } + } + return bSent; +} + +/*********************************************************************//** + * @brief Receive a block of data via UART peripheral + * @param[in] UARTx Selected UART peripheral used to send data, + * should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[out] rxbuf Pointer to Received buffer + * @param[in] buflen Length of Received buffer + * @param[in] flag Flag mode, should be NONE_BLOCKING or BLOCKING + + * @return Number of bytes received + * + * Note: when using UART in BLOCKING mode, a time-out condition is used + * via defined symbol UART_BLOCKING_TIMEOUT. + **********************************************************************/ +uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \ + uint32_t buflen, TRANSFER_BLOCK_Type flag) +{ + uint32_t bToRecv, bRecv, timeOut; + uint8_t *pChar = rxbuf; + + bToRecv = buflen; + + // Blocking mode + if (flag == BLOCKING) { + bRecv = 0; + while (bToRecv){ + timeOut = UART_BLOCKING_TIMEOUT; + while (!(UARTx->LSR & UART_LSR_RDR)){ + if (timeOut == 0) break; + timeOut--; + } + // Time out! + if(timeOut == 0) break; + // Get data from the buffer + (*pChar++) = UART_ReceiveByte(UARTx); + bToRecv--; + bRecv++; + } + } + // None blocking mode + else { + bRecv = 0; + while (bToRecv) { + if (!(UARTx->LSR & UART_LSR_RDR)) { + break; + } else { + (*pChar++) = UART_ReceiveByte(UARTx); + bRecv++; + bToRecv--; + } + } + } + return bRecv; +} + +/*********************************************************************//** + * @brief Force BREAK character on UART line, output pin UARTx TXD is + forced to logic 0. + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return None + **********************************************************************/ +void UART_ForceBreak(LPC_UART_TypeDef* UARTx) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN; + } + else + { + UARTx->LCR |= UART_LCR_BREAK_EN; + } +} + + +/********************************************************************//** + * @brief Enable or disable specified UART interrupt. + * @param[in] UARTx UART peripheral selected, should be + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] UARTIntCfg Specifies the interrupt flag, + * should be one of the following: + - UART_INTCFG_RBR : RBR Interrupt enable + - UART_INTCFG_THRE : THR Interrupt enable + - UART_INTCFG_RLS : RX line status interrupt enable + - UART1_INTCFG_MS : Modem status interrupt enable (UART1 only) + - UART1_INTCFG_CTS : CTS1 signal transition interrupt enable (UART1 only) + - UART_INTCFG_ABEO : Enables the end of auto-baud interrupt + - UART_INTCFG_ABTO : Enables the auto-baud time-out interrupt + * @param[in] NewState New state of specified UART interrupt type, + * should be: + * - ENALBE: Enable this UART interrupt type. +* - DISALBE: Disable this UART interrupt type. + * @return None + *********************************************************************/ +void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState) +{ + uint32_t tmp = 0; + + CHECK_PARAM(PARAM_UARTx(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + switch(UARTIntCfg){ + case UART_INTCFG_RBR: + tmp = UART_IER_RBRINT_EN; + break; + case UART_INTCFG_THRE: + tmp = UART_IER_THREINT_EN; + break; + case UART_INTCFG_RLS: + tmp = UART_IER_RLSINT_EN; + break; + case UART1_INTCFG_MS: + tmp = UART1_IER_MSINT_EN; + break; + case UART1_INTCFG_CTS: + tmp = UART1_IER_CTSINT_EN; + break; + case UART_INTCFG_ABEO: + tmp = UART_IER_ABEOINT_EN; + break; + case UART_INTCFG_ABTO: + tmp = UART_IER_ABTOINT_EN; + break; + } + + if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) + { + CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg))); + } + else + { + CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg)); + } + + if (NewState == ENABLE) + { + if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp; + } + else + { + UARTx->/*DLIER.*/IER |= tmp; + } + } + else + { + if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK; + } + else + { + UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK; + } + } +} + + +/********************************************************************//** + * @brief Get current value of Line Status register in UART peripheral. + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return Current value of Line Status register in UART peripheral. + * Note: The return value of this function must be ANDed with each member in + * UART_LS_Type enumeration to determine current flag status + * corresponding to each Line status type. Because some flags in + * Line Status register will be cleared after reading, the next reading + * Line Status register could not be correct. So this function used to + * read Line status register in one time only, then the return value + * used to check all flags. + *********************************************************************/ +uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK); + } + else + { + return ((UARTx->LSR) & UART_LSR_BITMASK); + } +} + +/********************************************************************//** + * @brief Get Interrupt Identification value + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return Current value of UART UIIR register in UART peripheral. + *********************************************************************/ +uint32_t UART_GetIntId(LPC_UART_TypeDef* UARTx) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + return (UARTx->IIR & 0x03CF); +} + +/*********************************************************************//** + * @brief Check whether if UART is busy or not + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @return RESET if UART is not busy, otherwise return SET. + **********************************************************************/ +FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx) +{ + if (UARTx->LSR & UART_LSR_TEMT){ + return RESET; + } else { + return SET; + } +} + + +/*********************************************************************//** + * @brief Configure FIFO function on selected UART peripheral + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] FIFOCfg Pointer to a UART_FIFO_CFG_Type Structure that + * contains specified information about FIFO configuration + * @return none + **********************************************************************/ +void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg) +{ + uint8_t tmp = 0; + + CHECK_PARAM(PARAM_UARTx(UARTx)); + CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf)); + + tmp |= UART_FCR_FIFO_EN; + switch (FIFOCfg->FIFO_Level){ + case UART_FIFO_TRGLEV0: + tmp |= UART_FCR_TRG_LEV0; + break; + case UART_FIFO_TRGLEV1: + tmp |= UART_FCR_TRG_LEV1; + break; + case UART_FIFO_TRGLEV2: + tmp |= UART_FCR_TRG_LEV2; + break; + case UART_FIFO_TRGLEV3: + default: + tmp |= UART_FCR_TRG_LEV3; + break; + } + + if (FIFOCfg->FIFO_ResetTxBuf == ENABLE) + { + tmp |= UART_FCR_TX_RS; + } + if (FIFOCfg->FIFO_ResetRxBuf == ENABLE) + { + tmp |= UART_FCR_RX_RS; + } + if (FIFOCfg->FIFO_DMAMode == ENABLE) + { + tmp |= UART_FCR_DMAMODE_SEL; + } + + + //write to FIFO control register + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK; + } + else + { + UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK; + } +} + +/*****************************************************************************//** +* @brief Fills each UART_FIFOInitStruct member with its default value: +* - FIFO_DMAMode = DISABLE +* - FIFO_Level = UART_FIFO_TRGLEV0 +* - FIFO_ResetRxBuf = ENABLE +* - FIFO_ResetTxBuf = ENABLE +* - FIFO_State = ENABLE + +* @param[in] UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure +* which will be initialized. +* @return None +*******************************************************************************/ +void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct) +{ + UART_FIFOInitStruct->FIFO_DMAMode = DISABLE; + UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0; + UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE; + UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE; +} + + +/*********************************************************************//** + * @brief Start/Stop Auto Baudrate activity + * @param[in] UARTx UART peripheral selected, should be + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] ABConfigStruct A pointer to UART_AB_CFG_Type structure that + * contains specified information about UART + * auto baudrate configuration + * @param[in] NewState New State of Auto baudrate activity, should be: + * - ENABLE: Start this activity + * - DISABLE: Stop this activity + * Note: Auto-baudrate mode enable bit will be cleared once this mode + * completed. + * @return none + **********************************************************************/ +void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \ + FunctionalState NewState) +{ + uint32_t tmp; + + CHECK_PARAM(PARAM_UARTx(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + tmp = 0; + if (NewState == ENABLE) { + if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){ + tmp |= UART_ACR_MODE; + } + if (ABConfigStruct->AutoRestart == ENABLE){ + tmp |= UART_ACR_AUTO_RESTART; + } + } + + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + if (NewState == ENABLE) + { + // Clear DLL and DLM value + ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN; + ((LPC_UART1_TypeDef *)UARTx)->DLL = 0; + ((LPC_UART1_TypeDef *)UARTx)->DLM = 0; + ((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN; + // FDR value must be reset to default value + ((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10; + ((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp; + } + else + { + ((LPC_UART1_TypeDef *)UARTx)->ACR = 0; + } + } + else + { + if (NewState == ENABLE) + { + // Clear DLL and DLM value + UARTx->LCR |= UART_LCR_DLAB_EN; + UARTx->DLL = 0; + UARTx->DLM = 0; + UARTx->LCR &= ~UART_LCR_DLAB_EN; + // FDR value must be reset to default value + UARTx->FDR = 0x10; + UARTx->ACR = UART_ACR_START | tmp; + } + else + { + UARTx->ACR = 0; + } + } +} + +/*********************************************************************//** + * @brief Clear Autobaud Interrupt Pending + * @param[in] UARTx UART peripheral selected, should be + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] ABIntType type of auto-baud interrupt, should be: + * - UART_AUTOBAUD_INTSTAT_ABEO: End of Auto-baud interrupt + * - UART_AUTOBAUD_INTSTAT_ABTO: Auto-baud time out interrupt + * @return none + **********************************************************************/ +void UART_ABClearIntPending(LPC_UART_TypeDef *UARTx, UART_ABEO_Type ABIntType) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + UARTx->ACR |= ABIntType; + } + else + UARTx->ACR |= ABIntType; +} + +/*********************************************************************//** + * @brief Enable/Disable transmission on UART TxD pin + * @param[in] UARTx UART peripheral selected, should be: + * - LPC_UART0: UART0 peripheral + * - LPC_UART1: UART1 peripheral + * - LPC_UART2: UART2 peripheral + * - LPC_UART3: UART3 peripheral + * @param[in] NewState New State of Tx transmission function, should be: + * - ENABLE: Enable this function + - DISABLE: Disable this function + * @return none + **********************************************************************/ +void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_UARTx(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN; + } + else + { + UARTx->TER |= UART_TER_TXEN; + } + } + else + { + if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1) + { + ((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; + } + else + { + UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK; + } + } +} + +/* UART IrDA functions ---------------------------------------------------*/ + +#ifdef _UART3 + +/*********************************************************************//** + * @brief Enable or disable inverting serial input function of IrDA + * on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) + * @param[in] NewState New state of inverting serial input, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return none + **********************************************************************/ +void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_UART_IrDA(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + UARTx->ICR |= UART_ICR_IRDAINV; + } + else if (NewState == DISABLE) + { + UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Enable or disable IrDA function on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) + * @param[in] NewState New state of IrDA function, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return none + **********************************************************************/ +void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState) +{ + CHECK_PARAM(PARAM_UART_IrDA(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + if (NewState == ENABLE) + { + UARTx->ICR |= UART_ICR_IRDAEN; + } + else + { + UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Configure Pulse divider for IrDA function on UART peripheral. + * @param[in] UARTx UART peripheral selected, should be LPC_UART3 (only) + * @param[in] PulseDiv Pulse Divider value from Peripheral clock, + * should be one of the following: + - UART_IrDA_PULSEDIV2 : Pulse width = 2 * Tpclk + - UART_IrDA_PULSEDIV4 : Pulse width = 4 * Tpclk + - UART_IrDA_PULSEDIV8 : Pulse width = 8 * Tpclk + - UART_IrDA_PULSEDIV16 : Pulse width = 16 * Tpclk + - UART_IrDA_PULSEDIV32 : Pulse width = 32 * Tpclk + - UART_IrDA_PULSEDIV64 : Pulse width = 64 * Tpclk + - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk + - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk + + * @return none + **********************************************************************/ +void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv) +{ + uint32_t tmp, tmp1; + CHECK_PARAM(PARAM_UART_IrDA(UARTx)); + CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv)); + + tmp1 = UART_ICR_PULSEDIV(PulseDiv); + tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7)); + tmp |= tmp1 | UART_ICR_FIXPULSE_EN; + UARTx->ICR = tmp & UART_ICR_BITMASK; +} + +#endif + + +/* UART1 FullModem function ---------------------------------------------*/ + +#ifdef _UART1 + +/*********************************************************************//** + * @brief Force pin DTR/RTS corresponding to given state (Full modem mode) + * @param[in] UARTx LPC_UART1 (only) + * @param[in] Pin Pin that NewState will be applied to, should be: + * - UART1_MODEM_PIN_DTR: DTR pin. + * - UART1_MODEM_PIN_RTS: RTS pin. + * @param[in] NewState New State of DTR/RTS pin, should be: + * - INACTIVE: Force the pin to inactive signal. + - ACTIVE: Force the pin to active signal. + * @return none + **********************************************************************/ +void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \ + UART1_SignalState NewState) +{ + uint8_t tmp = 0; + + CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); + CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin)); + CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState)); + + switch (Pin){ + case UART1_MODEM_PIN_DTR: + tmp = UART1_MCR_DTR_CTRL; + break; + case UART1_MODEM_PIN_RTS: + tmp = UART1_MCR_RTS_CTRL; + break; + default: + break; + } + + if (NewState == ACTIVE){ + UARTx->MCR |= tmp; + } else { + UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Configure Full Modem mode for UART peripheral + * @param[in] UARTx LPC_UART1 (only) + * @param[in] Mode Full Modem mode, should be: + * - UART1_MODEM_MODE_LOOPBACK: Loop back mode. + * - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode. + * - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode. + * @param[in] NewState New State of this mode, should be: + * - ENABLE: Enable this mode. + - DISABLE: Disable this mode. + * @return none + **********************************************************************/ +void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \ + FunctionalState NewState) +{ + uint8_t tmp = 0; + + CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); + CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); + + switch(Mode){ + case UART1_MODEM_MODE_LOOPBACK: + tmp = UART1_MCR_LOOPB_EN; + break; + case UART1_MODEM_MODE_AUTO_RTS: + tmp = UART1_MCR_AUTO_RTS_EN; + break; + case UART1_MODEM_MODE_AUTO_CTS: + tmp = UART1_MCR_AUTO_CTS_EN; + break; + default: + break; + } + + if (NewState == ENABLE) + { + UARTx->MCR |= tmp; + } + else + { + UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK; + } +} + + +/*********************************************************************//** + * @brief Get current status of modem status register + * @param[in] UARTx LPC_UART1 (only) + * @return Current value of modem status register + * Note: The return value of this function must be ANDed with each member + * UART_MODEM_STAT_type enumeration to determine current flag status + * corresponding to each modem flag status. Because some flags in + * modem status register will be cleared after reading, the next reading + * modem register could not be correct. So this function used to + * read modem status register in one time only, then the return value + * used to check all flags. + **********************************************************************/ +uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx) +{ + CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); + return ((UARTx->MSR) & UART1_MSR_BITMASK); +} + + +/* UART RS485 functions --------------------------------------------------------------*/ + +/*********************************************************************//** + * @brief Configure UART peripheral in RS485 mode according to the specified +* parameters in the RS485ConfigStruct. + * @param[in] UARTx LPC_UART1 (only) + * @param[in] RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure +* that contains the configuration information for specified UART +* in RS485 mode. + * @return None + **********************************************************************/ +void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct) +{ + uint32_t tmp; + + CHECK_PARAM(PARAM_UART1_MODEM(UARTx)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State)); + CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue)); + CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level)); + CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin)); + CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State)); + CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State)); + + tmp = 0; + // If Auto Direction Control is enabled - This function is used in Master mode + if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE) + { + tmp |= UART1_RS485CTRL_DCTRL_EN; + + // Set polar + if (RS485ConfigStruct->DirCtrlPol_Level == SET) + { + tmp |= UART1_RS485CTRL_OINV_1; + } + + // Set pin according to + if (RS485ConfigStruct->DirCtrlPin == UART1_RS485_DIRCTRL_DTR) + { + tmp |= UART1_RS485CTRL_SEL_DTR; + } + + // Fill delay time + UARTx->RS485DLY = RS485ConfigStruct->DelayValue & UART1_RS485DLY_BITMASK; + } + + // MultiDrop mode is enable + if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE) + { + tmp |= UART1_RS485CTRL_NMM_EN; + } + + // Auto Address Detect function + if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE) + { + tmp |= UART1_RS485CTRL_AADEN; + // Fill Match Address + UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART1_RS485ADRMATCH_BITMASK; + } + + + // Receiver is disable + if (RS485ConfigStruct->Rx_State == DISABLE) + { + tmp |= UART1_RS485CTRL_RX_DIS; + } + + // write back to RS485 control register + UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK; + + // Enable Parity function and leave parity in stick '0' parity as default + UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN); +} + +/*********************************************************************//** + * @brief Enable/Disable receiver in RS485 module in UART1 + * @param[in] UARTx LPC_UART1 (only) + * @param[in] NewState New State of command, should be: + * - ENABLE: Enable this function. + * - DISABLE: Disable this function. + * @return None + **********************************************************************/ +void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState) +{ + if (NewState == ENABLE){ + UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS; + } else { + UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS; + } +} + +/*********************************************************************//** + * @brief Send data on RS485 bus with specified parity stick value (9-bit mode). + * @param[in] UARTx LPC_UART1 (only) + * @param[in] pDatFrm Pointer to data frame. + * @param[in] size Size of data. + * @param[in] ParityStick Parity Stick value, should be 0 or 1. + * @return None + **********************************************************************/ +uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \ + uint32_t size, uint8_t ParityStick) +{ + uint8_t tmp, save; + uint32_t cnt; + + if (ParityStick){ + save = tmp = UARTx->LCR & UART_LCR_BITMASK; + tmp &= ~(UART_LCR_PARITY_EVEN); + UARTx->LCR = tmp; + cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING); + while (!(UARTx->LSR & UART_LSR_TEMT)); + UARTx->LCR = save; + } else { + cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING); + while (!(UARTx->LSR & UART_LSR_TEMT)); + } + return cnt; +} + +/*********************************************************************//** + * @brief Send Slave address frames on RS485 bus. + * @param[in] UARTx LPC_UART1 (only) + * @param[in] SlvAddr Slave Address. + * @return None + **********************************************************************/ +void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr) +{ + UART_RS485Send(UARTx, &SlvAddr, 1, 1); +} + +/*********************************************************************//** + * @brief Send Data frames on RS485 bus. + * @param[in] UARTx LPC_UART1 (only) + * @param[in] pData Pointer to data to be sent. + * @param[in] size Size of data frame to be sent. + * @return None + **********************************************************************/ +uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size) +{ + return (UART_RS485Send(UARTx, pData, size, 0)); +} + +#endif /* _UART1 */ + +#endif /* _UART */ + +/** + * @} + */ + +/** + * @} + */ +/* --------------------------------- End Of File ------------------------------ */ +
diff -r 000000000000 -r 84d7747641aa lpc17xx_uart.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_uart.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,644 @@ +/***********************************************************************//** + * @file lpc17xx_uart.h + * @brief Contains all macro definitions and function prototypes + * support for UART firmware library on LPC17xx + * @version 3.0 + * @date 18. June. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup UART UART + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef __LPC17XX_UART_H +#define __LPC17XX_UART_H + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup UART_Public_Macros UART Public Macros + * @{ + */ + +/** UART time-out definitions in case of using Read() and Write function + * with Blocking Flag mode + */ +#define UART_BLOCKING_TIMEOUT (0xFFFFFFFFUL) + +/** + * @} + */ + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ + +/* Accepted Error baud rate value (in percent unit) */ +#define UART_ACCEPTED_BAUDRATE_ERROR (3) /*!< Acceptable UART baudrate error */ + + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Receiver Buffer Register + **********************************************************************/ +#define UART_RBR_MASKBIT ((uint8_t)0xFF) /*!< UART Received Buffer mask bit (8 bits) */ + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Transmit Holding Register + **********************************************************************/ +#define UART_THR_MASKBIT ((uint8_t)0xFF) /*!< UART Transmit Holding mask bit (8 bits) */ + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Divisor Latch LSB register + **********************************************************************/ +#define UART_LOAD_DLL(div) ((div) & 0xFF) /**< Macro for loading least significant halfs of divisors */ +#define UART_DLL_MASKBIT ((uint8_t)0xFF) /*!< Divisor latch LSB bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UARTn Divisor Latch MSB register + **********************************************************************/ +#define UART_DLM_MASKBIT ((uint8_t)0xFF) /*!< Divisor latch MSB bit mask */ +#define UART_LOAD_DLM(div) (((div) >> 8) & 0xFF) /**< Macro for loading most significant halfs of divisors */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART interrupt enable register + **********************************************************************/ +#define UART_IER_RBRINT_EN ((uint32_t)(1<<0)) /*!< RBR Interrupt enable*/ +#define UART_IER_THREINT_EN ((uint32_t)(1<<1)) /*!< THR Interrupt enable*/ +#define UART_IER_RLSINT_EN ((uint32_t)(1<<2)) /*!< RX line status interrupt enable*/ +#define UART1_IER_MSINT_EN ((uint32_t)(1<<3)) /*!< Modem status interrupt enable */ +#define UART1_IER_CTSINT_EN ((uint32_t)(1<<7)) /*!< CTS1 signal transition interrupt enable */ +#define UART_IER_ABEOINT_EN ((uint32_t)(1<<8)) /*!< Enables the end of auto-baud interrupt */ +#define UART_IER_ABTOINT_EN ((uint32_t)(1<<9)) /*!< Enables the auto-baud time-out interrupt */ +#define UART_IER_BITMASK ((uint32_t)(0x307)) /*!< UART interrupt enable register bit mask */ +#define UART1_IER_BITMASK ((uint32_t)(0x38F)) /*!< UART1 interrupt enable register bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART interrupt identification register + **********************************************************************/ +#define UART_IIR_INTSTAT_PEND ((uint32_t)(1<<0)) /*!<Interrupt Status - Active low */ +#define UART_IIR_INTID_RLS ((uint32_t)(3<<1)) /*!<Interrupt identification: Receive line status*/ +#define UART_IIR_INTID_RDA ((uint32_t)(2<<1)) /*!<Interrupt identification: Receive data available*/ +#define UART_IIR_INTID_CTI ((uint32_t)(6<<1)) /*!<Interrupt identification: Character time-out indicator*/ +#define UART_IIR_INTID_THRE ((uint32_t)(1<<1)) /*!<Interrupt identification: THRE interrupt*/ +#define UART1_IIR_INTID_MODEM ((uint32_t)(0<<1)) /*!<Interrupt identification: Modem interrupt*/ +#define UART_IIR_INTID_MASK ((uint32_t)(7<<1)) /*!<Interrupt identification: Interrupt ID mask */ +#define UART_IIR_FIFO_EN ((uint32_t)(3<<6)) /*!<These bits are equivalent to UnFCR[0] */ +#define UART_IIR_ABEO_INT ((uint32_t)(1<<8)) /*!< End of auto-baud interrupt */ +#define UART_IIR_ABTO_INT ((uint32_t)(1<<9)) /*!< Auto-baud time-out interrupt */ +#define UART_IIR_BITMASK ((uint32_t)(0x3CF)) /*!< UART interrupt identification register bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART FIFO control register + **********************************************************************/ +#define UART_FCR_FIFO_EN ((uint8_t)(1<<0)) /*!< UART FIFO enable */ +#define UART_FCR_RX_RS ((uint8_t)(1<<1)) /*!< UART FIFO RX reset */ +#define UART_FCR_TX_RS ((uint8_t)(1<<2)) /*!< UART FIFO TX reset */ +#define UART_FCR_DMAMODE_SEL ((uint8_t)(1<<3)) /*!< UART DMA mode selection */ +#define UART_FCR_TRG_LEV0 ((uint8_t)(0)) /*!< UART FIFO trigger level 0: 1 character */ +#define UART_FCR_TRG_LEV1 ((uint8_t)(1<<6)) /*!< UART FIFO trigger level 1: 4 character */ +#define UART_FCR_TRG_LEV2 ((uint8_t)(2<<6)) /*!< UART FIFO trigger level 2: 8 character */ +#define UART_FCR_TRG_LEV3 ((uint8_t)(3<<6)) /*!< UART FIFO trigger level 3: 14 character */ +#define UART_FCR_BITMASK ((uint8_t)(0xCF)) /*!< UART FIFO control bit mask */ +#define UART_TX_FIFO_SIZE (16) + +/*********************************************************************//** + * Macro defines for Macro defines for UART line control register + **********************************************************************/ +#define UART_LCR_WLEN5 ((uint8_t)(0)) /*!< UART 5 bit data mode */ +#define UART_LCR_WLEN6 ((uint8_t)(1<<0)) /*!< UART 6 bit data mode */ +#define UART_LCR_WLEN7 ((uint8_t)(2<<0)) /*!< UART 7 bit data mode */ +#define UART_LCR_WLEN8 ((uint8_t)(3<<0)) /*!< UART 8 bit data mode */ +#define UART_LCR_STOPBIT_SEL ((uint8_t)(1<<2)) /*!< UART Two Stop Bits Select */ +#define UART_LCR_PARITY_EN ((uint8_t)(1<<3)) /*!< UART Parity Enable */ +#define UART_LCR_PARITY_ODD ((uint8_t)(0)) /*!< UART Odd Parity Select */ +#define UART_LCR_PARITY_EVEN ((uint8_t)(1<<4)) /*!< UART Even Parity Select */ +#define UART_LCR_PARITY_F_1 ((uint8_t)(2<<4)) /*!< UART force 1 stick parity */ +#define UART_LCR_PARITY_F_0 ((uint8_t)(3<<4)) /*!< UART force 0 stick parity */ +#define UART_LCR_BREAK_EN ((uint8_t)(1<<6)) /*!< UART Transmission Break enable */ +#define UART_LCR_DLAB_EN ((uint8_t)(1<<7)) /*!< UART Divisor Latches Access bit enable */ +#define UART_LCR_BITMASK ((uint8_t)(0xFF)) /*!< UART line control bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 Modem Control Register + **********************************************************************/ +#define UART1_MCR_DTR_CTRL ((uint8_t)(1<<0)) /*!< Source for modem output pin DTR */ +#define UART1_MCR_RTS_CTRL ((uint8_t)(1<<1)) /*!< Source for modem output pin RTS */ +#define UART1_MCR_LOOPB_EN ((uint8_t)(1<<4)) /*!< Loop back mode select */ +#define UART1_MCR_AUTO_RTS_EN ((uint8_t)(1<<6)) /*!< Enable Auto RTS flow-control */ +#define UART1_MCR_AUTO_CTS_EN ((uint8_t)(1<<7)) /*!< Enable Auto CTS flow-control */ +#define UART1_MCR_BITMASK ((uint8_t)(0x0F3)) /*!< UART1 bit mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART line status register + **********************************************************************/ +#define UART_LSR_RDR ((uint8_t)(1<<0)) /*!<Line status register: Receive data ready*/ +#define UART_LSR_OE ((uint8_t)(1<<1)) /*!<Line status register: Overrun error*/ +#define UART_LSR_PE ((uint8_t)(1<<2)) /*!<Line status register: Parity error*/ +#define UART_LSR_FE ((uint8_t)(1<<3)) /*!<Line status register: Framing error*/ +#define UART_LSR_BI ((uint8_t)(1<<4)) /*!<Line status register: Break interrupt*/ +#define UART_LSR_THRE ((uint8_t)(1<<5)) /*!<Line status register: Transmit holding register empty*/ +#define UART_LSR_TEMT ((uint8_t)(1<<6)) /*!<Line status register: Transmitter empty*/ +#define UART_LSR_RXFE ((uint8_t)(1<<7)) /*!<Error in RX FIFO*/ +#define UART_LSR_BITMASK ((uint8_t)(0xFF)) /*!<UART Line status bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART Modem (UART1 only) status register + **********************************************************************/ +#define UART1_MSR_DELTA_CTS ((uint8_t)(1<<0)) /*!< Set upon state change of input CTS */ +#define UART1_MSR_DELTA_DSR ((uint8_t)(1<<1)) /*!< Set upon state change of input DSR */ +#define UART1_MSR_LO2HI_RI ((uint8_t)(1<<2)) /*!< Set upon low to high transition of input RI */ +#define UART1_MSR_DELTA_DCD ((uint8_t)(1<<3)) /*!< Set upon state change of input DCD */ +#define UART1_MSR_CTS ((uint8_t)(1<<4)) /*!< Clear To Send State */ +#define UART1_MSR_DSR ((uint8_t)(1<<5)) /*!< Data Set Ready State */ +#define UART1_MSR_RI ((uint8_t)(1<<6)) /*!< Ring Indicator State */ +#define UART1_MSR_DCD ((uint8_t)(1<<7)) /*!< Data Carrier Detect State */ +#define UART1_MSR_BITMASK ((uint8_t)(0xFF)) /*!< MSR register bit-mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART Scratch Pad Register + **********************************************************************/ +#define UART_SCR_BIMASK ((uint8_t)(0xFF)) /*!< UART Scratch Pad bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART Auto baudrate control register + **********************************************************************/ +#define UART_ACR_START ((uint32_t)(1<<0)) /**< UART Auto-baud start */ +#define UART_ACR_MODE ((uint32_t)(1<<1)) /**< UART Auto baudrate Mode 1 */ +#define UART_ACR_AUTO_RESTART ((uint32_t)(1<<2)) /**< UART Auto baudrate restart */ +#define UART_ACR_ABEOINT_CLR ((uint32_t)(1<<8)) /**< UART End of auto-baud interrupt clear */ +#define UART_ACR_ABTOINT_CLR ((uint32_t)(1<<9)) /**< UART Auto-baud time-out interrupt clear */ +#define UART_ACR_BITMASK ((uint32_t)(0x307)) /**< UART Auto Baudrate register bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART IrDA control register + **********************************************************************/ +#define UART_ICR_IRDAEN ((uint32_t)(1<<0)) /**< IrDA mode enable */ +#define UART_ICR_IRDAINV ((uint32_t)(1<<1)) /**< IrDA serial input inverted */ +#define UART_ICR_FIXPULSE_EN ((uint32_t)(1<<2)) /**< IrDA fixed pulse width mode */ +#define UART_ICR_PULSEDIV(n) ((uint32_t)((n&0x07)<<3)) /**< PulseDiv - Configures the pulse when FixPulseEn = 1 */ +#define UART_ICR_BITMASK ((uint32_t)(0x3F)) /*!< UART IRDA bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART Fractional divider register + **********************************************************************/ +#define UART_FDR_DIVADDVAL(n) ((uint32_t)(n&0x0F)) /**< Baud-rate generation pre-scaler divisor */ +#define UART_FDR_MULVAL(n) ((uint32_t)((n<<4)&0xF0)) /**< Baud-rate pre-scaler multiplier value */ +#define UART_FDR_BITMASK ((uint32_t)(0xFF)) /**< UART Fractional Divider register bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART Tx Enable register + **********************************************************************/ +#define UART_TER_TXEN ((uint8_t)(1<<7)) /*!< Transmit enable bit */ +#define UART_TER_BITMASK ((uint8_t)(0x80)) /**< UART Transmit Enable Register bit mask */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 RS485 Control register + **********************************************************************/ +#define UART1_RS485CTRL_NMM_EN ((uint32_t)(1<<0)) /*!< RS-485/EIA-485 Normal Multi-drop Mode (NMM) + is disabled */ +#define UART1_RS485CTRL_RX_DIS ((uint32_t)(1<<1)) /*!< The receiver is disabled */ +#define UART1_RS485CTRL_AADEN ((uint32_t)(1<<2)) /*!< Auto Address Detect (AAD) is enabled */ +#define UART1_RS485CTRL_SEL_DTR ((uint32_t)(1<<3)) /*!< If direction control is enabled + (bit DCTRL = 1), pin DTR is used for direction control */ +#define UART1_RS485CTRL_DCTRL_EN ((uint32_t)(1<<4)) /*!< Enable Auto Direction Control */ +#define UART1_RS485CTRL_OINV_1 ((uint32_t)(1<<5)) /*!< This bit reverses the polarity of the direction + control signal on the RTS (or DTR) pin. The direction control pin + will be driven to logic "1" when the transmitter has data to be sent */ +#define UART1_RS485CTRL_BITMASK ((uint32_t)(0x3F)) /**< RS485 control bit-mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 RS-485 Address Match register + **********************************************************************/ +#define UART1_RS485ADRMATCH_BITMASK ((uint8_t)(0xFF)) /**< Bit mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART1 RS-485 Delay value register + **********************************************************************/ +/* Macro defines for UART1 RS-485 Delay value register */ +#define UART1_RS485DLY_BITMASK ((uint8_t)(0xFF)) /** Bit mask value */ + +/*********************************************************************//** + * Macro defines for Macro defines for UART FIFO Level register + **********************************************************************/ +#define UART_FIFOLVL_RXFIFOLVL(n) ((uint32_t)(n&0x0F)) /**< Reflects the current level of the UART receiver FIFO */ +#define UART_FIFOLVL_TXFIFOLVL(n) ((uint32_t)((n>>8)&0x0F)) /**< Reflects the current level of the UART transmitter FIFO */ +#define UART_FIFOLVL_BITMASK ((uint32_t)(0x0F0F)) /**< UART FIFO Level Register bit mask */ + + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ + +/** Macro to check the input UART_DATABIT parameters */ +#define PARAM_UART_DATABIT(databit) ((databit==UART_DATABIT_5) || (databit==UART_DATABIT_6)\ +|| (databit==UART_DATABIT_7) || (databit==UART_DATABIT_8)) + +/** Macro to check the input UART_STOPBIT parameters */ +#define PARAM_UART_STOPBIT(stopbit) ((stopbit==UART_STOPBIT_1) || (stopbit==UART_STOPBIT_2)) + +/** Macro to check the input UART_PARITY parameters */ +#define PARAM_UART_PARITY(parity) ((parity==UART_PARITY_NONE) || (parity==UART_PARITY_ODD) \ +|| (parity==UART_PARITY_EVEN) || (parity==UART_PARITY_SP_1) \ +|| (parity==UART_PARITY_SP_0)) + +/** Macro to check the input UART_FIFO parameters */ +#define PARAM_UART_FIFO_LEVEL(fifo) ((fifo==UART_FIFO_TRGLEV0) \ +|| (fifo==UART_FIFO_TRGLEV1) || (fifo==UART_FIFO_TRGLEV2) \ +|| (fifo==UART_FIFO_TRGLEV3)) + +/** Macro to check the input UART_INTCFG parameters */ +#define PARAM_UART_INTCFG(IntCfg) ((IntCfg==UART_INTCFG_RBR) || (IntCfg==UART_INTCFG_THRE) \ +|| (IntCfg==UART_INTCFG_RLS) || (IntCfg==UART_INTCFG_ABEO) \ +|| (IntCfg==UART_INTCFG_ABTO)) + +/** Macro to check the input UART1_INTCFG parameters - expansion input parameter for UART1 */ +#define PARAM_UART1_INTCFG(IntCfg) ((IntCfg==UART1_INTCFG_MS) || (IntCfg==UART1_INTCFG_CTS)) + +/** Macro to check the input UART_AUTOBAUD_MODE parameters */ +#define PARAM_UART_AUTOBAUD_MODE(ABmode) ((ABmode==UART_AUTOBAUD_MODE0) || (ABmode==UART_AUTOBAUD_MODE1)) + +/** Macro to check the input UART_AUTOBAUD_INTSTAT parameters */ +#define PARAM_UART_AUTOBAUD_INTSTAT(ABIntStat) ((ABIntStat==UART_AUTOBAUD_INTSTAT_ABEO) || \ + (ABIntStat==UART_AUTOBAUD_INTSTAT_ABTO)) + +/** Macro to check the input UART_IrDA_PULSEDIV parameters */ +#define PARAM_UART_IrDA_PULSEDIV(PulseDiv) ((PulseDiv==UART_IrDA_PULSEDIV2) || (PulseDiv==UART_IrDA_PULSEDIV4) \ +|| (PulseDiv==UART_IrDA_PULSEDIV8) || (PulseDiv==UART_IrDA_PULSEDIV16) \ +|| (PulseDiv==UART_IrDA_PULSEDIV32) || (PulseDiv==UART_IrDA_PULSEDIV64) \ +|| (PulseDiv==UART_IrDA_PULSEDIV128) || (PulseDiv==UART_IrDA_PULSEDIV256)) + +/* Macro to check the input UART1_SignalState parameters */ +#define PARAM_UART1_SIGNALSTATE(x) ((x==INACTIVE) || (x==ACTIVE)) + +/** Macro to check the input PARAM_UART1_MODEM_PIN parameters */ +#define PARAM_UART1_MODEM_PIN(x) ((x==UART1_MODEM_PIN_DTR) || (x==UART1_MODEM_PIN_RTS)) + +/** Macro to check the input PARAM_UART1_MODEM_MODE parameters */ +#define PARAM_UART1_MODEM_MODE(x) ((x==UART1_MODEM_MODE_LOOPBACK) || (x==UART1_MODEM_MODE_AUTO_RTS) \ +|| (x==UART1_MODEM_MODE_AUTO_CTS)) + +/** Macro to check the direction control pin type */ +#define PARAM_UART_RS485_DIRCTRL_PIN(x) ((x==UART1_RS485_DIRCTRL_RTS) || (x==UART1_RS485_DIRCTRL_DTR)) + +/* Macro to determine if it is valid UART port number */ +#define PARAM_UARTx(x) ((((uint32_t *)x)==((uint32_t *)LPC_UART0)) \ +|| (((uint32_t *)x)==((uint32_t *)LPC_UART1)) \ +|| (((uint32_t *)x)==((uint32_t *)LPC_UART2)) \ +|| (((uint32_t *)x)==((uint32_t *)LPC_UART3))) +#define PARAM_UART_IrDA(x) (((uint32_t *)x)==((uint32_t *)LPC_UART3)) +#define PARAM_UART1_MODEM(x) (((uint32_t *)x)==((uint32_t *)LPC_UART1)) + +/** Macro to check the input value for UART1_RS485_CFG_MATCHADDRVALUE parameter */ +#define PARAM_UART1_RS485_CFG_MATCHADDRVALUE(x) ((x<0xFF)) + +/** Macro to check the input value for UART1_RS485_CFG_DELAYVALUE parameter */ +#define PARAM_UART1_RS485_CFG_DELAYVALUE(x) ((x<0xFF)) + +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup UART_Public_Types UART Public Types + * @{ + */ + +/** + * @brief UART Databit type definitions + */ +typedef enum { + UART_DATABIT_5 = 0, /*!< UART 5 bit data mode */ + UART_DATABIT_6, /*!< UART 6 bit data mode */ + UART_DATABIT_7, /*!< UART 7 bit data mode */ + UART_DATABIT_8 /*!< UART 8 bit data mode */ +} UART_DATABIT_Type; + +/** + * @brief UART Stop bit type definitions + */ +typedef enum { + UART_STOPBIT_1 = (0), /*!< UART 1 Stop Bits Select */ + UART_STOPBIT_2, /*!< UART Two Stop Bits Select */ +} UART_STOPBIT_Type; + +/** + * @brief UART Parity type definitions + */ +typedef enum { + UART_PARITY_NONE = 0, /*!< No parity */ + UART_PARITY_ODD, /*!< Odd parity */ + UART_PARITY_EVEN, /*!< Even parity */ + UART_PARITY_SP_1, /*!< Forced "1" stick parity */ + UART_PARITY_SP_0 /*!< Forced "0" stick parity */ +} UART_PARITY_Type; + +/** + * @brief FIFO Level type definitions + */ +typedef enum { + UART_FIFO_TRGLEV0 = 0, /*!< UART FIFO trigger level 0: 1 character */ + UART_FIFO_TRGLEV1, /*!< UART FIFO trigger level 1: 4 character */ + UART_FIFO_TRGLEV2, /*!< UART FIFO trigger level 2: 8 character */ + UART_FIFO_TRGLEV3 /*!< UART FIFO trigger level 3: 14 character */ +} UART_FITO_LEVEL_Type; + +/********************************************************************//** +* @brief UART Interrupt Type definitions +**********************************************************************/ +typedef enum { + UART_INTCFG_RBR = 0, /*!< RBR Interrupt enable*/ + UART_INTCFG_THRE, /*!< THR Interrupt enable*/ + UART_INTCFG_RLS, /*!< RX line status interrupt enable*/ + UART1_INTCFG_MS, /*!< Modem status interrupt enable (UART1 only) */ + UART1_INTCFG_CTS, /*!< CTS1 signal transition interrupt enable (UART1 only) */ + UART_INTCFG_ABEO, /*!< Enables the end of auto-baud interrupt */ + UART_INTCFG_ABTO /*!< Enables the auto-baud time-out interrupt */ +} UART_INT_Type; + +/** + * @brief UART Line Status Type definition + */ +typedef enum { + UART_LINESTAT_RDR = UART_LSR_RDR, /*!<Line status register: Receive data ready*/ + UART_LINESTAT_OE = UART_LSR_OE, /*!<Line status register: Overrun error*/ + UART_LINESTAT_PE = UART_LSR_PE, /*!<Line status register: Parity error*/ + UART_LINESTAT_FE = UART_LSR_FE, /*!<Line status register: Framing error*/ + UART_LINESTAT_BI = UART_LSR_BI, /*!<Line status register: Break interrupt*/ + UART_LINESTAT_THRE = UART_LSR_THRE, /*!<Line status register: Transmit holding register empty*/ + UART_LINESTAT_TEMT = UART_LSR_TEMT, /*!<Line status register: Transmitter empty*/ + UART_LINESTAT_RXFE = UART_LSR_RXFE /*!<Error in RX FIFO*/ +} UART_LS_Type; + +/** + * @brief UART Auto-baudrate mode type definition + */ +typedef enum { + UART_AUTOBAUD_MODE0 = 0, /**< UART Auto baudrate Mode 0 */ + UART_AUTOBAUD_MODE1, /**< UART Auto baudrate Mode 1 */ +} UART_AB_MODE_Type; + +/** + * @brief Auto Baudrate mode configuration type definition + */ +typedef struct { + UART_AB_MODE_Type ABMode; /**< Autobaudrate mode */ + FunctionalState AutoRestart; /**< Auto Restart state */ +} UART_AB_CFG_Type; + +/** + * @brief UART End of Auto-baudrate type definition + */ +typedef enum { + UART_AUTOBAUD_INTSTAT_ABEO = UART_IIR_ABEO_INT, /**< UART End of auto-baud interrupt */ + UART_AUTOBAUD_INTSTAT_ABTO = UART_IIR_ABTO_INT /**< UART Auto-baud time-out interrupt */ +}UART_ABEO_Type; + +/** + * UART IrDA Control type Definition + */ +typedef enum { + UART_IrDA_PULSEDIV2 = 0, /**< Pulse width = 2 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV4, /**< Pulse width = 4 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV8, /**< Pulse width = 8 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV16, /**< Pulse width = 16 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV32, /**< Pulse width = 32 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV64, /**< Pulse width = 64 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV128, /**< Pulse width = 128 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ + UART_IrDA_PULSEDIV256 /**< Pulse width = 256 * Tpclk + - Configures the pulse when FixPulseEn = 1 */ +} UART_IrDA_PULSE_Type; + +/********************************************************************//** +* @brief UART1 Full modem - Signal states definition +**********************************************************************/ +typedef enum { + INACTIVE = 0, /* In-active state */ + ACTIVE = !INACTIVE /* Active state */ +}UART1_SignalState; + +/** + * @brief UART modem status type definition + */ +typedef enum { + UART1_MODEM_STAT_DELTA_CTS = UART1_MSR_DELTA_CTS, /*!< Set upon state change of input CTS */ + UART1_MODEM_STAT_DELTA_DSR = UART1_MSR_DELTA_DSR, /*!< Set upon state change of input DSR */ + UART1_MODEM_STAT_LO2HI_RI = UART1_MSR_LO2HI_RI, /*!< Set upon low to high transition of input RI */ + UART1_MODEM_STAT_DELTA_DCD = UART1_MSR_DELTA_DCD, /*!< Set upon state change of input DCD */ + UART1_MODEM_STAT_CTS = UART1_MSR_CTS, /*!< Clear To Send State */ + UART1_MODEM_STAT_DSR = UART1_MSR_DSR, /*!< Data Set Ready State */ + UART1_MODEM_STAT_RI = UART1_MSR_RI, /*!< Ring Indicator State */ + UART1_MODEM_STAT_DCD = UART1_MSR_DCD /*!< Data Carrier Detect State */ +} UART_MODEM_STAT_type; + +/** + * @brief Modem output pin type definition + */ +typedef enum { + UART1_MODEM_PIN_DTR = 0, /*!< Source for modem output pin DTR */ + UART1_MODEM_PIN_RTS /*!< Source for modem output pin RTS */ +} UART_MODEM_PIN_Type; + +/** + * @brief UART Modem mode type definition + */ +typedef enum { + UART1_MODEM_MODE_LOOPBACK = 0, /*!< Loop back mode select */ + UART1_MODEM_MODE_AUTO_RTS, /*!< Enable Auto RTS flow-control */ + UART1_MODEM_MODE_AUTO_CTS /*!< Enable Auto CTS flow-control */ +} UART_MODEM_MODE_Type; + +/** + * @brief UART Direction Control Pin type definition + */ +typedef enum { + UART1_RS485_DIRCTRL_RTS = 0, /**< Pin RTS is used for direction control */ + UART1_RS485_DIRCTRL_DTR /**< Pin DTR is used for direction control */ +} UART_RS485_DIRCTRL_PIN_Type; + +/********************************************************************//** +* @brief UART Configuration Structure definition +**********************************************************************/ +typedef struct { + uint32_t Baud_rate; /**< UART baud rate */ + UART_PARITY_Type Parity; /**< Parity selection, should be: + - UART_PARITY_NONE: No parity + - UART_PARITY_ODD: Odd parity + - UART_PARITY_EVEN: Even parity + - UART_PARITY_SP_1: Forced "1" stick parity + - UART_PARITY_SP_0: Forced "0" stick parity + */ + UART_DATABIT_Type Databits; /**< Number of data bits, should be: + - UART_DATABIT_5: UART 5 bit data mode + - UART_DATABIT_6: UART 6 bit data mode + - UART_DATABIT_7: UART 7 bit data mode + - UART_DATABIT_8: UART 8 bit data mode + */ + UART_STOPBIT_Type Stopbits; /**< Number of stop bits, should be: + - UART_STOPBIT_1: UART 1 Stop Bits Select + - UART_STOPBIT_2: UART 2 Stop Bits Select + */ +} UART_CFG_Type; + +/********************************************************************//** +* @brief UART FIFO Configuration Structure definition +**********************************************************************/ + +typedef struct { + FunctionalState FIFO_ResetRxBuf; /**< Reset Rx FIFO command state , should be: + - ENABLE: Reset Rx FIFO in UART + - DISABLE: Do not reset Rx FIFO in UART + */ + FunctionalState FIFO_ResetTxBuf; /**< Reset Tx FIFO command state , should be: + - ENABLE: Reset Tx FIFO in UART + - DISABLE: Do not reset Tx FIFO in UART + */ + FunctionalState FIFO_DMAMode; /**< DMA mode, should be: + - ENABLE: Enable DMA mode in UART + - DISABLE: Disable DMA mode in UART + */ + UART_FITO_LEVEL_Type FIFO_Level; /**< Rx FIFO trigger level, should be: + - UART_FIFO_TRGLEV0: UART FIFO trigger level 0: 1 character + - UART_FIFO_TRGLEV1: UART FIFO trigger level 1: 4 character + - UART_FIFO_TRGLEV2: UART FIFO trigger level 2: 8 character + - UART_FIFO_TRGLEV3: UART FIFO trigger level 3: 14 character + */ +} UART_FIFO_CFG_Type; + +/********************************************************************//** +* @brief UART1 Full modem - RS485 Control configuration type +**********************************************************************/ +typedef struct { + FunctionalState NormalMultiDropMode_State; /*!< Normal MultiDrop mode State: + - ENABLE: Enable this function. + - DISABLE: Disable this function. */ + FunctionalState Rx_State; /*!< Receiver State: + - ENABLE: Enable Receiver. + - DISABLE: Disable Receiver. */ + FunctionalState AutoAddrDetect_State; /*!< Auto Address Detect mode state: + - ENABLE: ENABLE this function. + - DISABLE: Disable this function. */ + FunctionalState AutoDirCtrl_State; /*!< Auto Direction Control State: + - ENABLE: Enable this function. + - DISABLE: Disable this function. */ + UART_RS485_DIRCTRL_PIN_Type DirCtrlPin; /*!< If direction control is enabled, state: + - UART1_RS485_DIRCTRL_RTS: + pin RTS is used for direction control. + - UART1_RS485_DIRCTRL_DTR: + pin DTR is used for direction control. */ + SetState DirCtrlPol_Level; /*!< Polarity of the direction control signal on + the RTS (or DTR) pin: + - RESET: The direction control pin will be driven + to logic "0" when the transmitter has data to be sent. + - SET: The direction control pin will be driven + to logic "1" when the transmitter has data to be sent. */ + uint8_t MatchAddrValue; /*!< address match value for RS-485/EIA-485 mode, 8-bit long */ + uint8_t DelayValue; /*!< delay time is in periods of the baud clock, 8-bit long */ +} UART1_RS485_CTRLCFG_Type; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup UART_Public_Functions UART Public Functions + * @{ + */ +/* UART Init/DeInit functions --------------------------------------------------*/ +void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct); +void UART_DeInit(LPC_UART_TypeDef* UARTx); +void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct); + +/* UART Send/Receive functions -------------------------------------------------*/ +void UART_SendByte(LPC_UART_TypeDef* UARTx, uint8_t Data); +uint8_t UART_ReceiveByte(LPC_UART_TypeDef* UARTx); +uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf, + uint32_t buflen, TRANSFER_BLOCK_Type flag); +uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \ + uint32_t buflen, TRANSFER_BLOCK_Type flag); + +/* UART FIFO functions ----------------------------------------------------------*/ +void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg); +void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct); + +/* UART get information functions -----------------------------------------------*/ +uint32_t UART_GetIntId(LPC_UART_TypeDef* UARTx); +uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx); + +/* UART operate functions -------------------------------------------------------*/ +void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, \ + FunctionalState NewState); +void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState); +FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx); +void UART_ForceBreak(LPC_UART_TypeDef* UARTx); + +/* UART Auto-baud functions -----------------------------------------------------*/ +void UART_ABClearIntPending(LPC_UART_TypeDef *UARTx, UART_ABEO_Type ABIntType); +void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \ + FunctionalState NewState); + +/* UART1 FullModem functions ----------------------------------------------------*/ +void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \ + UART1_SignalState NewState); +void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \ + FunctionalState NewState); +uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx); + +/* UART RS485 functions ----------------------------------------------------------*/ +void UART_RS485Config(LPC_UART1_TypeDef *UARTx, \ + UART1_RS485_CTRLCFG_Type *RS485ConfigStruct); +void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState); +void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr); +uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size); + +/* UART IrDA functions-------------------------------------------------------------*/ +void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState); +void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState); +void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv); +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __LPC17XX_UART_H */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_wdt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_wdt.c Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,261 @@ +/***********************************************************************//** + * @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 + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **********************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @addtogroup 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 = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4)); + // Check if it valid + if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX)) + { + 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 = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4)); + + if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX)) + { + 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 = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4)); + + if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX)) + { + 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 = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4)); + + if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX)) + { + 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 = (((pclk_wdt) / WDT_US_INDEX) * (timeout / 4)); + // Check if it valid + if ((tempval >= WDT_TIMEOUT_MIN) && (tempval <= WDT_TIMEOUT_MAX)) + { + 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 ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc17xx_wdt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc17xx_wdt.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,142 @@ +/***********************************************************************//** + * @file lpc17xx_wdt.h + * @brief Contains all macro definitions and function prototypes + * support for WDT firmware library on LPC17xx + * @version 2.0 + * @date 21. May. 2010 + * @author NXP MCU SW Application Team + ************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + **************************************************************************/ + +/* Peripheral group ----------------------------------------------------------- */ +/** @defgroup WDT WDT + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC17XX_WDT_H_ +#define LPC17XX_WDT_H_ + +/* Includes ------------------------------------------------------------------- */ +#include "LPC17xx.h" +#include "lpc_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Private Macros ------------------------------------------------------------- */ +/** @defgroup WDT_Private_Macros WDT Private Macros + * @{ + */ + +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/** WDT interrupt enable bit */ +#define WDT_WDMOD_WDEN ((uint32_t)(1<<0)) +/** WDT interrupt enable bit */ +#define WDT_WDMOD_WDRESET ((uint32_t)(1<<1)) +/** WDT time out flag bit */ +#define WDT_WDMOD_WDTOF ((uint32_t)(1<<2)) +/** WDT Time Out flag bit */ +#define WDT_WDMOD_WDINT ((uint32_t)(1<<3)) +/** WDT Mode */ +#define WDT_WDMOD(n) ((uint32_t)(1<<1)) + +/** Define divider index for microsecond ( us ) */ +#define WDT_US_INDEX ((uint32_t)(1000000)) +/** WDT Time out minimum value */ +#define WDT_TIMEOUT_MIN ((uint32_t)(0xFF)) +/** WDT Time out maximum value */ +#define WDT_TIMEOUT_MAX ((uint32_t)(0xFFFFFFFF)) + +/** Watchdog mode register mask */ +#define WDT_WDMOD_MASK (uint8_t)(0x02) +/** Watchdog timer constant register mask */ +#define WDT_WDTC_MASK (uint8_t)(0xFFFFFFFF) +/** Watchdog feed sequence register mask */ +#define WDT_WDFEED_MASK (uint8_t)(0x000000FF) +/** Watchdog timer value register mask */ +#define WDT_WDCLKSEL_MASK (uint8_t)(0x03) +/** Clock selected from internal RC */ +#define WDT_WDCLKSEL_RC (uint8_t)(0x00) +/** Clock selected from PCLK */ +#define WDT_WDCLKSEL_PCLK (uint8_t)(0x01) +/** Clock selected from external RTC */ +#define WDT_WDCLKSEL_RTC (uint8_t)(0x02) + +/* ---------------- CHECK PARAMETER DEFINITIONS ---------------------------- */ +/* Macro check clock source selection */ +#define PARAM_WDT_CLK_OPT(OPTION) ((OPTION ==WDT_CLKSRC_IRC)||(OPTION ==WDT_CLKSRC_IRC)\ +||(OPTION ==WDT_CLKSRC_IRC)) + +/* Macro check WDT mode */ +#define PARAM_WDT_MODE_OPT(OPTION) ((OPTION ==WDT_MODE_INT_ONLY)||(OPTION ==WDT_MODE_RESET)) +/** + * @} + */ + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup WDT_Public_Types WDT Public Types + * @{ + */ + +/** @brief Clock source option for WDT */ +typedef enum { + WDT_CLKSRC_IRC = 0, /*!< Clock source from Internal RC oscillator */ + WDT_CLKSRC_PCLK = 1, /*!< Selects the APB peripheral clock (PCLK) */ + WDT_CLKSRC_RTC = 2 /*!< Selects the RTC oscillator */ +} WDT_CLK_OPT; + +/** @brief WDT operation mode */ +typedef enum { + WDT_MODE_INT_ONLY = 0, /*!< Use WDT to generate interrupt only */ + WDT_MODE_RESET = 1 /*!< Use WDT to generate interrupt and reset MCU */ +} WDT_MODE_OPT; + +/** + * @} + */ + + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup WDT_Public_Functions WDT Public Functions + * @{ + */ + +void WDT_Init (WDT_CLK_OPT ClkSrc, WDT_MODE_OPT WDTMode); +void WDT_Start(uint32_t TimeOut); +void WDT_Feed (void); +void WDT_UpdateTimeOut ( uint32_t TimeOut); +FlagStatus WDT_ReadTimeOutFlag (void); +void WDT_ClrTimeOutFlag (void); +uint32_t WDT_GetCurrentCount(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LPC17XX_WDT_H_ */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 84d7747641aa lpc_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc_types.h Sun Mar 20 18:45:15 2011 +0000 @@ -0,0 +1,196 @@ +/***********************************************************************//** + * @file lpc_types.h + * @brief Contains the NXP ABL typedefs for C standard types. + * It is intended to be used in ISO C conforming development + * environments and checks for this insofar as it is possible + * to do so. + * @version 1.0 + * @date 27 Jul. 2008 + * @author wellsk + ************************************************************************** + * 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. + **************************************************************************/ + +/* Type group ----------------------------------------------------------- */ +/** @defgroup LPC_Types LPC_Types + * @ingroup LPC1700CMSIS_FwLib_Drivers + * @{ + */ + +#ifndef LPC_TYPES_H +#define LPC_TYPES_H + +/* Includes ------------------------------------------------------------------- */ +#include <stdint.h> + + +/* Public Types --------------------------------------------------------------- */ +/** @defgroup LPC_Types_Public_Types LPC_Types Public Types + * @{ + */ + +/** + * @brief Boolean Type definition + */ +typedef enum {FALSE = 0, TRUE = !FALSE} Bool; + +/** + * @brief Flag Status and Interrupt Flag Status type definition + */ +typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState; +#define PARAM_SETSTATE(State) ((State==RESET) || (State==SET)) + +/** + * @brief Functional State Definition + */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define PARAM_FUNCTIONALSTATE(State) ((State==DISABLE) || (State==ENABLE)) + +/** + * @ Status type definition + */ +typedef enum {ERROR = 0, SUCCESS = !ERROR} Status; + + +/** + * Read/Write transfer type mode (Block or non-block) + */ +typedef enum +{ + NONE_BLOCKING = 0, /**< None Blocking type */ + BLOCKING, /**< Blocking type */ +} TRANSFER_BLOCK_Type; + + +/** Pointer to Function returning Void (any number of parameters) */ +typedef void (*PFV)(); + +/** Pointer to Function returning int32_t (any number of parameters) */ +typedef int32_t(*PFI)(); + +/** + * @} + */ + + +/* Public Macros -------------------------------------------------------------- */ +/** @defgroup LPC_Types_Public_Macros LPC_Types Public Macros + * @{ + */ + +/* _BIT(n) sets the bit at position "n" + * _BIT(n) is intended to be used in "OR" and "AND" expressions: + * e.g., "(_BIT(3) | _BIT(7))". + */ +#undef _BIT +/* Set bit macro */ +#define _BIT(n) (1<<n) + +/* _SBF(f,v) sets the bit field starting at position "f" to value "v". + * _SBF(f,v) is intended to be used in "OR" and "AND" expressions: + * e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)" + */ +#undef _SBF +/* Set bit field macro */ +#define _SBF(f,v) (v<<f) + +/* _BITMASK constructs a symbol with 'field_width' least significant + * bits set. + * e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF + * The symbol is intended to be used to limit the bit field width + * thusly: + * <a_register> = (any_expression) & _BITMASK(x), where 0 < x <= 32. + * If "any_expression" results in a value that is larger than can be + * contained in 'x' bits, the bits above 'x - 1' are masked off. When + * used with the _SBF example above, the example would be written: + * a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16)) + * This ensures that the value written to a_reg is no wider than + * 16 bits, and makes the code easier to read and understand. + */ +#undef _BITMASK +/* Bitmask creation macro */ +#define _BITMASK(field_width) ( _BIT(field_width) - 1) + +/* NULL pointer */ +#ifndef NULL +#define NULL ((void*) 0) +#endif + +/* Number of elements in an array */ +#define NELEMENTS(array) (sizeof (array) / sizeof (array[0])) + +/* Static data/function define */ +#define STATIC static +/* External data/function define */ +#define EXTERN extern + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/** + * @} + */ + + +/* Old Type Definition compatibility ------------------------------------------ */ +/** @addtogroup LPC_Types_Public_Types LPC_Types Public Types + * @{ + */ + +/** SMA type for character type */ +typedef char CHAR; + +/** SMA type for 8 bit unsigned value */ +typedef uint8_t UNS_8; + +/** SMA type for 8 bit signed value */ +typedef int8_t INT_8; + +/** SMA type for 16 bit unsigned value */ +typedef uint16_t UNS_16; + +/** SMA type for 16 bit signed value */ +typedef int16_t INT_16; + +/** SMA type for 32 bit unsigned value */ +typedef uint32_t UNS_32; + +/** SMA type for 32 bit signed value */ +typedef int32_t INT_32; + +/** SMA type for 64 bit signed value */ +typedef int64_t INT_64; + +/** SMA type for 64 bit unsigned value */ +typedef uint64_t UNS_64; + +/** 32 bit boolean type */ +typedef Bool BOOL_32; + +/** 16 bit boolean type */ +typedef Bool BOOL_16; + +/** 8 bit boolean type */ +typedef Bool BOOL_8; + +/** + * @} + */ + + +#endif /* LPC_TYPES_H */ + +/** + * @} + */ + +/* --------------------------------- End Of File ------------------------------ */