lpc13xx build ok (not work) with lpcopen

This commit is contained in:
hathach
2018-11-30 23:39:18 +07:00
parent 804c60304e
commit d246cc2e6c
86 changed files with 15932 additions and 6276 deletions

View File

@@ -0,0 +1,287 @@
/*
* @brief LPC13xx A/D conversion driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/* Get the number of clock for a full conversion */
STATIC INLINE uint8_t getFullConvClk(void)
{
#if defined(CHIP_LPC1347)
return 31;
#else
return 11;
#endif
}
/* Get divider value */
STATIC uint8_t getClkDiv(LPC_ADC_T *pADC, bool burstMode, uint32_t adcRate, uint8_t clks)
{
uint32_t adcBlockFreq;
uint32_t fullAdcRate;
uint8_t div;
/* 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 4.5MHz.
A fully conversion requires (bits_accuracy+1) of these clocks.
ADC Clock = PCLK_ADC0 / (CLKDIV + 1);
ADC rate = ADC clock / (the number of clocks required for each conversion);
*/
adcBlockFreq = Chip_Clock_GetSystemClockRate();
#if defined(ADC_ACC_12BITS)
fullAdcRate = adcRate * getFullConvClk();
if (clks == ADC_10BITS) {
fullAdcRate /= 2;
}
#else
if (burstMode) {
fullAdcRate = adcRate * clks;
}
else {
fullAdcRate = adcRate * getFullConvClk();
}
#endif
/* Get the round value by fomular: (2*A + B)/(2*B) */
div = ((adcBlockFreq * 2 + fullAdcRate) / (fullAdcRate * 2)) - 1;
return div;
}
/* Set start mode for ADC */
void setStartMode(LPC_ADC_T *pADC, uint8_t start_mode)
{
uint32_t temp;
temp = pADC->CR & (~ADC_CR_START_MASK);
pADC->CR = temp | (ADC_CR_START_MODE_SEL((uint32_t) start_mode));
}
/* Get the ADC value */
Status readAdcVal(LPC_ADC_T *pADC, uint8_t channel, uint16_t *data)
{
uint32_t temp;
temp = pADC->DR[channel];
if (!ADC_DR_DONE(temp)) {
return ERROR;
}
/* if(ADC_DR_OVERRUN(temp) && (pADC->CR & ADC_CR_BURST)) */
/* return ERROR; */
*data = (uint16_t) ADC_DR_RESULT(temp);
return SUCCESS;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the ADC peripheral and the ADC setup structure to default value */
void Chip_ADC_Init(LPC_ADC_T *pADC, ADC_CLOCK_SETUP_T *ADCSetup)
{
uint8_t div;
uint32_t cr = 0;
uint32_t clk;
/* Power up ADC */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC_PD);
/* Enable ADC clock */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC);
#if defined(ADC_TRIM_SUPPORT)
pADC->ADTRM = 0xF00;
#endif
pADC->INTEN = 0; /* Disable all interrupts */
#if defined(CHIP_LPC1347)
cr |= ADC_CR_LPWRMODE;
#else
cr |= ADC_CR_PDN;
#endif
ADCSetup->adcRate = ADC_MAX_SAMPLE_RATE;
#if defined(CHIP_LPC1347)
ADCSetup->bitsAccuracy = ADC_12BITS;
clk = ADC_12BITS;
#else
ADCSetup->bitsAccuracy = ADC_10BITS;
clk = 11;
#endif
ADCSetup->burstMode = false;
div = getClkDiv(pADC, false, ADCSetup->adcRate, clk);
cr |= ADC_CR_CLKDIV(div);
#if !defined(ADC_ACC_12BITS)
cr |= ADC_CR_BITACC(ADCSetup->bitsAccuracy);
#endif /*defined(ADC_ACC_12BITS)*/
pADC->CR = cr;
}
/* Shutdown ADC */
void Chip_ADC_DeInit(LPC_ADC_T *pADC)
{
pADC->INTEN = 0x00000100;
pADC->CR = 0;
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC);
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC_PD);
}
/* Get the ADC value */
Status Chip_ADC_ReadValue(LPC_ADC_T *pADC, uint8_t channel, uint16_t *data)
{
return readAdcVal(pADC, channel, data);
}
/* Get ADC Channel status from ADC data register */
FlagStatus Chip_ADC_ReadStatus(LPC_ADC_T *pADC, uint8_t channel, uint32_t StatusType)
{
switch (StatusType) {
case ADC_DR_DONE_STAT:
return (pADC->STAT & (1UL << channel)) ? SET : RESET;
case ADC_DR_OVERRUN_STAT:
channel += 8;
return (pADC->STAT & (1UL << channel)) ? SET : RESET;
case ADC_DR_ADINT_STAT:
return pADC->STAT >> 16 ? SET : RESET;
default:
break;
}
return RESET;
}
/* Enable/Disable interrupt for ADC channel */
void Chip_ADC_Int_SetChannelCmd(LPC_ADC_T *pADC, uint8_t channel, FunctionalState NewState)
{
if (NewState == ENABLE) {
pADC->INTEN |= (1UL << channel);
}
else {
pADC->INTEN &= (~(1UL << channel));
}
}
/* Select the mode starting the AD conversion */
void Chip_ADC_SetStartMode(LPC_ADC_T *pADC, ADC_START_MODE_T mode, ADC_EDGE_CFG_T EdgeOption)
{
if ((mode != ADC_START_NOW) && (mode != ADC_NO_START)) {
if (EdgeOption) {
pADC->CR |= ADC_CR_EDGE;
}
else {
pADC->CR &= ~ADC_CR_EDGE;
}
}
setStartMode(pADC, (uint8_t) mode);
}
/* Set the ADC Sample rate */
void Chip_ADC_SetSampleRate(LPC_ADC_T *pADC, ADC_CLOCK_SETUP_T *ADCSetup, uint32_t rate)
{
uint8_t div;
uint32_t cr;
cr = pADC->CR & (~ADC_SAMPLE_RATE_CONFIG_MASK);
ADCSetup->adcRate = rate;
#if defined(CHIP_LPC1347)
div = getClkDiv(pADC, ADCSetup->burstMode, rate, ADCSetup->bitsAccuracy);
if (ADCSetup->bitsAccuracy == ADC_10BITS) {
cr |= ADC_CR_MODE10BIT;
}
#else
div = getClkDiv(pADC, ADCSetup->burstMode, rate, (11 - ADCSetup->bitsAccuracy));
#endif
cr |= ADC_CR_CLKDIV(div);
#if !defined(ADC_ACC_12BITS)
cr |= ADC_CR_BITACC(ADCSetup->bitsAccuracy);
#endif /*defined(ADC_ACC_12BITS)*/
pADC->CR = cr;
}
/* Set the ADC accuracy bits */
void Chip_ADC_SetResolution(LPC_ADC_T *pADC, ADC_CLOCK_SETUP_T *ADCSetup, ADC_RESOLUTION_T resolution)
{
ADCSetup->bitsAccuracy = resolution;
Chip_ADC_SetSampleRate(pADC, ADCSetup, ADCSetup->adcRate);
}
/* Enable or disable the ADC channel on ADC peripheral */
void Chip_ADC_EnableChannel(LPC_ADC_T *pADC, ADC_CHANNEL_T channel, FunctionalState NewState)
{
if (NewState == ENABLE) {
pADC->CR |= ADC_CR_CH_SEL(channel);
}
else {
pADC->CR &= ~ADC_CR_START_MASK;
pADC->CR &= ~ADC_CR_CH_SEL(channel);
}
}
/* Enable burst mode */
void Chip_ADC_SetBurstCmd(LPC_ADC_T *pADC, FunctionalState NewState)
{
setStartMode(pADC, ADC_NO_START);
#if defined(CHIP_LPC1347)
pADC->INTEN &= ~(1 << 8);
#endif
if (NewState == DISABLE) {
pADC->CR &= ~ADC_CR_BURST;
}
else {
pADC->CR |= ADC_CR_BURST;
}
}
/* Read the ADC value and convert it to 8bits value */
Status Chip_ADC_ReadByte(LPC_ADC_T *pADC, ADC_CHANNEL_T channel, uint8_t *data)
{
uint16_t temp=0;
Status rt;
rt = readAdcVal(pADC, channel, &temp);
*data = (uint8_t) temp;
return rt;
}

View File

@@ -0,0 +1,71 @@
/*
* @brief LPC13xx Miscellaneous chip specific functions
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/* System Clock Frequency (Core Clock) */
uint32_t SystemCoreClock;
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Update system core clock rate, should be called if the system has
a clock rate change */
void SystemCoreClockUpdate(void)
{
/* CPU core speed */
SystemCoreClock = Chip_Clock_GetSystemClockRate();
}
void Chip_USB_Init(void)
{
/* power UP USB Phy and USB PLL */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPAD_PD);
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD);
Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_SYSOSC);
Chip_Clock_SetupUSBPLL(3,1);
while (!Chip_Clock_IsUSBPLLLocked()) {}
Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1);
}

View File

@@ -0,0 +1,261 @@
/*
* @brief LPC13XX System clock control functions
*
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Inprecise clock rates for the watchdog oscillator */
STATIC const uint32_t wdtOSCRate[WDTLFO_OSC_4_60 + 1] = {
0, /* WDT_OSC_ILLEGAL */
600000, /* WDT_OSC_0_60 */
1050000, /* WDT_OSC_1_05 */
1400000, /* WDT_OSC_1_40 */
1750000, /* WDT_OSC_1_75 */
2100000, /* WDT_OSC_2_10 */
2400000, /* WDT_OSC_2_40 */
2700000, /* WDT_OSC_2_70 */
3000000, /* WDT_OSC_3_00 */
3250000, /* WDT_OSC_3_25 */
3500000, /* WDT_OSC_3_50 */
3750000, /* WDT_OSC_3_75 */
4000000, /* WDT_OSC_4_00 */
4200000, /* WDT_OSC_4_20 */
4400000, /* WDT_OSC_4_40 */
4600000 /* WDT_OSC_4_60 */
};
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/* Compute a WDT or LFO rate */
STATIC uint32_t Chip_Clock_GetWDTLFORate(uint32_t reg)
{
uint32_t div;
CHIP_WDTLFO_OSC_T clk;
/* Get WDT oscillator settings */
clk = (CHIP_WDTLFO_OSC_T) ((reg >> 5) & 0xF);
div = reg & 0x1F;
/* Compute clock rate and divided by divde value */
return wdtOSCRate[clk] / ((div + 1) << 1);
}
/* Compute a PLL frequency */
STATIC uint32_t Chip_Clock_GetPLLFreq(uint32_t PLLReg, uint32_t inputRate)
{
uint32_t msel = ((PLLReg & 0x1F) + 1);
return inputRate * msel;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Set System PLL clock source */
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
{
LPC_SYSCTL->SYSPLLCLKSEL = (uint32_t) src;
#if defined(CHIP_LPC1343)
LPC_SYSCTL->SYSPLLCLKUEN = 0;
LPC_SYSCTL->SYSPLLCLKUEN = 1;
#endif
}
/* Bypass System Oscillator and set oscillator frequency range */
void Chip_Clock_SetPLLBypass(bool bypass, bool highfr)
{
uint32_t ctrl = 0;
if (bypass) {
ctrl |= (1 << 0);
}
if (highfr) {
ctrl |= (1 << 1);
}
LPC_SYSCTL->SYSOSCCTRL = ctrl;
}
/* Set USB PLL clock source */
void Chip_Clock_SetUSBPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
{
LPC_SYSCTL->USBPLLCLKSEL = (uint32_t) src;
#if defined(CHIP_LPC1343)
LPC_SYSCTL->USBPLLCLKUEN = 0;
LPC_SYSCTL->USBPLLCLKUEN = 1;
#endif
}
/* Set main system clock source */
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src)
{
LPC_SYSCTL->MAINCLKSEL = (uint32_t) src;
#if defined(CHIP_LPC1343)
LPC_SYSCTL->MAINCLKUEN = 0;
LPC_SYSCTL->MAINCLKUEN = 1;
#endif
}
/* Set USB clock source and divider */
void Chip_Clock_SetUSBClockSource(CHIP_SYSCTL_USBCLKSRC_T src, uint32_t div)
{
LPC_SYSCTL->USBCLKSEL = (uint32_t) src;
#if defined(CHIP_LPC1343)
LPC_SYSCTL->USBCLKUEN = 0;
LPC_SYSCTL->USBCLKUEN = 1;
#endif
LPC_SYSCTL->USBCLKDIV = div;
}
#if defined(CHIP_LPC1343)
/* Set WDT clock source and divider */
void Chip_Clock_SetWDTClockSource(CHIP_SYSCTL_WDTCLKSRC_T src, uint32_t div)
{
LPC_SYSCTL->WDTCLKSEL = (uint32_t) src;
LPC_SYSCTL->WDTCLKUEN = 0;
LPC_SYSCTL->WDTCLKUEN = 1;
LPC_SYSCTL->WDTCLKDIV = div;
}
#endif
/* Set CLKOUT clock source and divider */
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div)
{
LPC_SYSCTL->CLKOUTSEL = (uint32_t) src;
#if defined(CHIP_LPC1343)
LPC_SYSCTL->CLKOUTUEN = 0;
LPC_SYSCTL->CLKOUTUEN = 1;
#endif
LPC_SYSCTL->CLKOUTDIV = div;
}
/* Return estimated watchdog oscillator rate */
uint32_t Chip_Clock_GetWDTOSCRate(void)
{
return Chip_Clock_GetWDTLFORate(LPC_SYSCTL->WDTOSCCTRL);
}
/* Return System PLL input clock rate */
uint32_t Chip_Clock_GetSystemPLLInClockRate(void)
{
uint32_t clkRate;
switch ((CHIP_SYSCTL_PLLCLKSRC_T) (LPC_SYSCTL->SYSPLLCLKSEL & 0x3)) {
case SYSCTL_PLLCLKSRC_IRC:
clkRate = Chip_Clock_GetIntOscRate();
break;
case SYSCTL_PLLCLKSRC_SYSOSC:
clkRate = Chip_Clock_GetMainOscRate();
break;
default:
clkRate = 0;
}
return clkRate;
}
/* Return System PLL output clock rate */
uint32_t Chip_Clock_GetSystemPLLOutClockRate(void)
{
return Chip_Clock_GetPLLFreq(LPC_SYSCTL->SYSPLLCTRL,
Chip_Clock_GetSystemPLLInClockRate());
}
/* Return USB PLL input clock rate */
uint32_t Chip_Clock_GetUSBPLLInClockRate(void)
{
uint32_t clkRate;
switch ((CHIP_SYSCTL_PLLCLKSRC_T) (LPC_SYSCTL->USBPLLCLKSEL & 0x3)) {
case SYSCTL_PLLCLKSRC_IRC:
clkRate = Chip_Clock_GetIntOscRate();
break;
case SYSCTL_PLLCLKSRC_SYSOSC:
clkRate = Chip_Clock_GetMainOscRate();
break;
default:
clkRate = 0;
}
return clkRate;
}
/* Return USB PLL output clock rate */
uint32_t Chip_Clock_GetUSBPLLOutClockRate(void)
{
return Chip_Clock_GetPLLFreq(LPC_SYSCTL->USBPLLCTRL,
Chip_Clock_GetUSBPLLInClockRate());
}
/* Return main clock rate */
uint32_t Chip_Clock_GetMainClockRate(void)
{
uint32_t clkRate = 0;
switch ((CHIP_SYSCTL_MAINCLKSRC_T) (LPC_SYSCTL->MAINCLKSEL & 0x3)) {
case SYSCTL_MAINCLKSRC_IRC:
clkRate = Chip_Clock_GetIntOscRate();
break;
case SYSCTL_MAINCLKSRC_PLLIN:
clkRate = Chip_Clock_GetSystemPLLInClockRate();
break;
case SYSCTL_MAINCLKSRC_WDTOSC:
clkRate = Chip_Clock_GetWDTOSCRate();
break;
case SYSCTL_MAINCLKSRC_PLLOUT:
clkRate = Chip_Clock_GetSystemPLLOutClockRate();
break;
}
return clkRate;
}
/* Return system clock rate */
uint32_t Chip_Clock_GetSystemClockRate(void)
{
/* No point in checking for divide by 0 */
return Chip_Clock_GetMainClockRate() / LPC_SYSCTL->SYSAHBCLKDIV;
}

View File

@@ -0,0 +1,82 @@
/*
* @brief LPC13xx Flash/EEPROM programming driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/*Read Part Identification number*/
void Chip_FLASH_ReadPartID(FLASH_READ_PART_ID_OUTPUT_T *pOutput)
{
FLASH_READ_PART_ID_COMMAND_T command;
command.cmd = FLASH_READ_PART_ID;
Chip_FLASH_Execute((FLASH_COMMAND_T *) &command, (FLASH_OUTPUT_T *) pOutput);
}
/*Read Boot code version number */
void Chip_FLASH_ReadBootCodeVersion(FLASH_READ_BOOTCODE_VER_OUTPUT_T *pOutput)
{
FLASH_READ_BOOTCODE_VER_COMMAND_T command;
command.cmd = FLASH_READ_BOOT_VER;
Chip_FLASH_Execute((FLASH_COMMAND_T *) &command, (FLASH_OUTPUT_T *) pOutput);
}
/* Reinvoke ISP */
void Chip_FLASH_ReInvokeISP(void)
{
FLASH_REINVOKE_ISP_COMMAND_T command;
FLASH_REINVOKE_ISP_OUTPUT_T output;
command.cmd = FLASH_REINVOKE_ISP;
Chip_FLASH_Execute((FLASH_COMMAND_T *) &command, (FLASH_OUTPUT_T *) &output);
}
/* Read UID */
void Chip_FLASH_ReadUID(FLASH_READ_UID_OUTPUT_T *pOutput)
{
FLASH_READ_UID_COMMAND_T command;
command.cmd = FLASH_READ_UID;
Chip_FLASH_Execute((FLASH_COMMAND_T *) &command, (FLASH_OUTPUT_T *) pOutput);
}

View File

@@ -0,0 +1,108 @@
/*
* @brief LPC13xx GPIO chip driver for LPC13(15/16/17/45/46/47) families
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#if defined(CHIP_LPC1347)
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize GPIO block */
void Chip_GPIO_Init(LPC_GPIO_T *pGPIO)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO);
}
/* De-Initialize GPIO block */
void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO);
}
/* Set a GPIO direction */
void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit, bool setting)
{
if (setting) {
pGPIO->DIR[port] |= 1UL << bit;
}
else {
pGPIO->DIR[port] &= ~(1UL << bit);
}
}
/* Set Direction for a GPIO port */
void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out)
{
if (out) {
pGPIO->DIR[portNum] |= bitValue;
}
else {
pGPIO->DIR[portNum] &= ~bitValue;
}
}
/* Set GPIO direction for a single GPIO pin */
void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output)
{
if (output) {
Chip_GPIO_SetPinDIROutput(pGPIO, port, pin);
}
else {
Chip_GPIO_SetPinDIRInput(pGPIO, port, pin);
}
}
/* Set GPIO direction for a all selected GPIO pins to an input or output */
void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask, bool outSet)
{
if (outSet) {
Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask);
}
else {
Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask);
}
}
#endif /* if defined(CHIP_LPC1347) */

View File

@@ -0,0 +1,140 @@
/*
* @brief LPC13xx GPIO chip driver for LPC13(11/13/42/43) families
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#if defined(CHIP_LPC1343)
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize GPIO block */
void Chip_GPIO_Init(LPC_GPIO_T *pGPIO)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO);
}
/* De-Initialize GPIO block */
void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO);
}
/* Set GPIO direction */
void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit, bool setting)
{
if (setting) {
pGPIO[port].DIR |= 1UL << bit;
}
else {
pGPIO[port].DIR &= ~(1UL << bit);
}
}
/* Set Direction for a GPIO port */
void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t bit, uint8_t out)
{
if (out) {
pGPIO[port].DIR |= bit;
}
else {
pGPIO[port].DIR &= ~bit;
}
}
/* Set GPIO direction for a single GPIO pin */
void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output)
{
if (output) {
Chip_GPIO_SetPinDIROutput(pGPIO, port, pin);
}
else {
Chip_GPIO_SetPinDIRInput(pGPIO, port, pin);
}
}
/* Set GPIO direction for a all selected GPIO pins to an input or output */
void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask, bool outSet)
{
if (outSet) {
Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask);
}
else {
Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask);
}
}
/* Composite function for setting up a full interrupt configuration for a single pin */
void Chip_GPIO_SetupPinInt(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, GPIO_INT_MODE_T mode)
{
uint32_t pinMask = (1 << pin);
/* Edge mode selected? */
if ((uint32_t) mode & 0x2) {
Chip_GPIO_SetPinModeEdge(pGPIO, port, pinMask);
/* Interrupt on both edges selected? */
if ((uint32_t) mode & 0x4) {
Chip_GPIO_SetEdgeModeBoth(pGPIO, port, pinMask);
}
else {
Chip_GPIO_SetEdgeModeSingle(pGPIO, port, pinMask);
}
}
else {
/* Level mode */
Chip_GPIO_SetPinModeLevel(pGPIO, port, pinMask);
}
/* Level selections will not alter 'dual edge' mode */
if ((uint32_t) mode & 0x1) {
/* High edge or level mode selected */
Chip_GPIO_SetModeHigh(pGPIO, port, pinMask);
}
else {
Chip_GPIO_SetModeLow(pGPIO, port, pinMask);
}
}
#endif /* if defined(CHIP_LPC1343) */

View File

@@ -0,0 +1,52 @@
/*
* @brief LPC13xx GPIO group driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#if defined(CHIP_LPC1347)
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
#endif /* defined(CHIP_LPC1347) */

View File

@@ -0,0 +1,548 @@
/*
* @brief LPC13xx I2C driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Control flags */
#define I2C_CON_FLAGS (I2C_CON_AA | I2C_CON_SI | I2C_CON_STO | I2C_CON_STA)
#define LPC_I2Cx(id) ((i2c[id].ip))
#define SLAVE_ACTIVE(iic) (((iic)->flags & 0xFF00) != 0)
/* I2C common interface structure */
struct i2c_interface {
LPC_I2C_T *ip; /* IP base address of the I2C device */
CHIP_SYSCTL_CLOCK_T clk; /* Clock used by I2C */
I2C_EVENTHANDLER_T mEvent; /* Current active Master event handler */
I2C_EVENTHANDLER_T sEvent; /* Slave transfer events */
I2C_XFER_T *mXfer; /* Current active xfer pointer */
I2C_XFER_T *sXfer; /* Pointer to store xfer when bus is busy */
uint32_t flags; /* Flags used by I2C master and slave */
};
/* Slave interface structure */
struct i2c_slave_interface {
I2C_XFER_T *xfer;
I2C_EVENTHANDLER_T event;
};
/* I2C interfaces */
static struct i2c_interface i2c[I2C_NUM_INTERFACE] = {
{LPC_I2C, SYSCTL_CLOCK_I2C, Chip_I2C_EventHandler, NULL, NULL, NULL, 0}
};
static struct i2c_slave_interface i2c_slave[I2C_NUM_INTERFACE][I2C_SLAVE_NUM_INTERFACE];
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
STATIC INLINE void enableClk(I2C_ID_T id)
{
Chip_Clock_EnablePeriphClock(i2c[id].clk);
}
STATIC INLINE void disableClk(I2C_ID_T id)
{
Chip_Clock_DisablePeriphClock(i2c[id].clk);
}
/* Get the ADC Clock Rate */
STATIC INLINE uint32_t getClkRate(I2C_ID_T id)
{
return Chip_Clock_GetSystemClockRate();
}
/* Enable I2C and start master transfer */
STATIC INLINE void startMasterXfer(LPC_I2C_T *pI2C)
{
/* Reset STA, STO, SI */
pI2C->CONCLR = I2C_CON_SI | I2C_CON_STO | I2C_CON_STA | I2C_CON_AA;
/* Enter to Master Transmitter mode */
pI2C->CONSET = I2C_CON_I2EN | I2C_CON_STA;
}
/* Enable I2C and enable slave transfers */
STATIC INLINE void startSlaverXfer(LPC_I2C_T *pI2C)
{
/* Reset STA, STO, SI */
pI2C->CONCLR = I2C_CON_SI | I2C_CON_STO | I2C_CON_STA;
/* Enter to Master Transmitter mode */
pI2C->CONSET = I2C_CON_I2EN | I2C_CON_AA;
}
/* Check if I2C bus is free */
STATIC INLINE int isI2CBusFree(LPC_I2C_T *pI2C)
{
return !(pI2C->CONSET & I2C_CON_STO);
}
/* Get current state of the I2C peripheral */
STATIC INLINE int getCurState(LPC_I2C_T *pI2C)
{
return (int) (pI2C->STAT & I2C_STAT_CODE_BITMASK);
}
/* Check if the active state belongs to master mode*/
STATIC INLINE int isMasterState(LPC_I2C_T *pI2C)
{
return getCurState(pI2C) < 0x60;
}
/* Set OWN slave address for specific slave ID */
STATIC void setSlaveAddr(LPC_I2C_T *pI2C, I2C_SLAVE_ID sid, uint8_t addr, uint8_t mask)
{
uint32_t index = (uint32_t) sid - 1;
pI2C->MASK[index] = mask;
if (sid == I2C_SLAVE_0) {
pI2C->ADR0 = addr;
}
else {
volatile uint32_t *abase = &pI2C->ADR1;
abase[index - 1] = addr;
}
}
/* Match the slave address */
STATIC int isSlaveAddrMatching(uint8_t addr1, uint8_t addr2, uint8_t mask)
{
mask |= 1;
return (addr1 & ~mask) == (addr2 & ~mask);
}
/* Get the index of the active slave */
STATIC I2C_SLAVE_ID lookupSlaveIndex(LPC_I2C_T *pI2C, uint8_t slaveAddr)
{
if (!(slaveAddr >> 1)) {
return I2C_SLAVE_GENERAL; /* General call address */
}
if (isSlaveAddrMatching(pI2C->ADR0, slaveAddr, pI2C->MASK[0])) {
return I2C_SLAVE_0;
}
if (isSlaveAddrMatching(pI2C->ADR1, slaveAddr, pI2C->MASK[1])) {
return I2C_SLAVE_1;
}
if (isSlaveAddrMatching(pI2C->ADR2, slaveAddr, pI2C->MASK[2])) {
return I2C_SLAVE_2;
}
if (isSlaveAddrMatching(pI2C->ADR3, slaveAddr, pI2C->MASK[3])) {
return I2C_SLAVE_3;
}
/* If everything is fine the code should never come here */
return I2C_SLAVE_GENERAL;
}
/* Master transfer state change handler handler */
int handleMasterXferState(LPC_I2C_T *pI2C, I2C_XFER_T *xfer)
{
uint32_t cclr = I2C_CON_FLAGS;
switch (getCurState(pI2C)) {
case 0x08: /* Start condition on bus */
case 0x10: /* Repeated start condition */
pI2C->DAT = (xfer->slaveAddr << 1) | (xfer->txSz == 0);
break;
/* Tx handling */
case 0x18: /* SLA+W sent and ACK received */
case 0x28: /* DATA sent and ACK received */
if (!xfer->txSz) {
cclr &= ~(xfer->rxSz ? I2C_CON_STA : I2C_CON_STO);
}
else {
pI2C->DAT = *xfer->txBuff++;
xfer->txSz--;
}
break;
/* Rx handling */
case 0x58: /* Data Received and NACK sent */
cclr &= ~I2C_CON_STO;
case 0x50: /* Data Received and ACK sent */
*xfer->rxBuff++ = pI2C->DAT;
xfer->rxSz--;
case 0x40: /* SLA+R sent and ACK received */
if (xfer->rxSz > 1) {
cclr &= ~I2C_CON_AA;
}
break;
/* NAK Handling */
case 0x20: /* SLA+W sent NAK received */
case 0x30: /* DATA sent NAK received */
case 0x48: /* SLA+R sent NAK received */
xfer->status = I2C_STATUS_NAK;
cclr &= ~I2C_CON_STO;
break;
case 0x38: /* Arbitration lost */
xfer->status = I2C_STATUS_ARBLOST;
break;
/* Bus Error */
case 0x00:
xfer->status = I2C_STATUS_BUSERR;
cclr &= ~I2C_CON_STO;
}
/* Set clear control flags */
pI2C->CONSET = cclr ^ I2C_CON_FLAGS;
pI2C->CONCLR = cclr;
/* If stopped return 0 */
if (!(cclr & I2C_CON_STO) || (xfer->status == I2C_STATUS_ARBLOST)) {
if (xfer->status == I2C_STATUS_BUSY) {
xfer->status = I2C_STATUS_DONE;
}
return 0;
}
return 1;
}
/* Find the slave address of SLA+W or SLA+R */
I2C_SLAVE_ID getSlaveIndex(LPC_I2C_T *pI2C)
{
switch (getCurState(pI2C)) {
case 0x60:
case 0x68:
case 0x70:
case 0x78:
case 0xA8:
case 0xB0:
return lookupSlaveIndex(pI2C, pI2C->DAT);
}
/* If everything is fine code should never come here */
return I2C_SLAVE_GENERAL;
}
/* Slave state machine handler */
int handleSlaveXferState(LPC_I2C_T *pI2C, I2C_XFER_T *xfer)
{
uint32_t cclr = I2C_CON_FLAGS;
int ret = RET_SLAVE_BUSY;
xfer->status = I2C_STATUS_BUSY;
switch (getCurState(pI2C)) {
case 0x80: /* SLA: Data received + ACK sent */
case 0x90: /* GC: Data received + ACK sent */
*xfer->rxBuff++ = pI2C->DAT;
xfer->rxSz--;
ret = RET_SLAVE_RX;
if (xfer->rxSz > 1) {
cclr &= ~I2C_CON_AA;
}
break;
case 0x60: /* Own SLA+W received */
case 0x68: /* Own SLA+W received after losing arbitration */
case 0x70: /* GC+W received */
case 0x78: /* GC+W received after losing arbitration */
xfer->slaveAddr = pI2C->DAT & ~1;
if (xfer->rxSz > 1) {
cclr &= ~I2C_CON_AA;
}
break;
case 0xA8: /* SLA+R received */
case 0xB0: /* SLA+R received after losing arbitration */
xfer->slaveAddr = pI2C->DAT & ~1;
case 0xB8: /* DATA sent and ACK received */
pI2C->DAT = *xfer->txBuff++;
xfer->txSz--;
if (xfer->txSz > 0) {
cclr &= ~I2C_CON_AA;
}
ret = RET_SLAVE_TX;
break;
case 0xC0: /* Data transmitted and NAK received */
case 0xC8: /* Last data transmitted and ACK received */
case 0x88: /* SLA: Data received + NAK sent */
case 0x98: /* GC: Data received + NAK sent */
case 0xA0: /* STOP/Repeated START condition received */
ret = RET_SLAVE_IDLE;
cclr &= ~I2C_CON_AA;
xfer->status = I2C_STATUS_DONE;
if (xfer->slaveAddr & 1) {
cclr &= ~I2C_CON_STA;
}
break;
}
/* Set clear control flags */
pI2C->CONSET = cclr ^ I2C_CON_FLAGS;
pI2C->CONCLR = cclr;
return ret;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Chip event handler interrupt based */
void Chip_I2C_EventHandler(I2C_ID_T id, I2C_EVENT_T event)
{
struct i2c_interface *iic = &i2c[id];
volatile I2C_STATUS_T *stat;
/* Only WAIT event needs to be handled */
if (event != I2C_EVENT_WAIT) {
return;
}
stat = &iic->mXfer->status;
/* Wait for the status to change */
while (*stat == I2C_STATUS_BUSY) {}
}
/* Chip polling event handler */
void Chip_I2C_EventHandlerPolling(I2C_ID_T id, I2C_EVENT_T event)
{
struct i2c_interface *iic = &i2c[id];
volatile I2C_STATUS_T *stat;
/* Only WAIT event needs to be handled */
if (event != I2C_EVENT_WAIT) {
return;
}
stat = &iic->mXfer->status;
/* Call the state change handler till xfer is done */
while (*stat == I2C_STATUS_BUSY) {
if (Chip_I2C_IsStateChanged(id)) {
Chip_I2C_MasterStateHandler(id);
}
}
}
/* Initializes the LPC_I2C peripheral with specified parameter */
void Chip_I2C_Init(I2C_ID_T id)
{
enableClk(id);
/* Set I2C operation to default */
LPC_I2Cx(id)->CONCLR = (I2C_CON_AA | I2C_CON_SI | I2C_CON_STA | I2C_CON_I2EN);
}
/* De-initializes the I2C peripheral registers to their default reset values */
void Chip_I2C_DeInit(I2C_ID_T id)
{
/* Disable I2C control */
LPC_I2Cx(id)->CONCLR = I2C_CON_I2EN | I2C_CON_SI | I2C_CON_STO | I2C_CON_STA | I2C_CON_AA;
disableClk(id);
}
/* Set up clock rate for LPC_I2C peripheral */
void Chip_I2C_SetClockRate(I2C_ID_T id, uint32_t clockrate)
{
uint32_t SCLValue;
SCLValue = (getClkRate(id) / clockrate);
LPC_I2Cx(id)->SCLH = (uint32_t) (SCLValue >> 1);
LPC_I2Cx(id)->SCLL = (uint32_t) (SCLValue - LPC_I2Cx(id)->SCLH);
}
/* Get current clock rate for LPC_I2C peripheral */
uint32_t Chip_I2C_GetClockRate(I2C_ID_T id)
{
return getClkRate(id) / (LPC_I2Cx(id)->SCLH + LPC_I2Cx(id)->SCLL);
}
/* Set the master event handler */
int Chip_I2C_SetMasterEventHandler(I2C_ID_T id, I2C_EVENTHANDLER_T event)
{
struct i2c_interface *iic = &i2c[id];
if (!iic->mXfer) {
iic->mEvent = event;
}
return iic->mEvent == event;
}
/* Get the master event handler */
I2C_EVENTHANDLER_T Chip_I2C_GetMasterEventHandler(I2C_ID_T id)
{
return i2c[id].mEvent;
}
/* Transmit and Receive data in master mode */
int Chip_I2C_MasterTransfer(I2C_ID_T id, I2C_XFER_T *xfer)
{
struct i2c_interface *iic = &i2c[id];
iic->mEvent(id, I2C_EVENT_LOCK);
xfer->status = I2C_STATUS_BUSY;
iic->mXfer = xfer;
/* If slave xfer not in progress */
if (!iic->sXfer) {
startMasterXfer(iic->ip);
}
iic->mEvent(id, I2C_EVENT_WAIT);
iic->mXfer = 0;
/* Wait for stop condition to appear on bus */
while (!isI2CBusFree(iic->ip)) {}
/* Start slave if one is active */
if (SLAVE_ACTIVE(iic)) {
startSlaverXfer(iic->ip);
}
iic->mEvent(id, I2C_EVENT_UNLOCK);
return (int) xfer->status;
}
/* Master tx only */
int Chip_I2C_MasterSend(I2C_ID_T id, uint8_t slaveAddr, const uint8_t *buff, uint8_t len)
{
I2C_XFER_T xfer = {0};
xfer.slaveAddr = slaveAddr;
xfer.txBuff = buff;
xfer.txSz = len;
while (Chip_I2C_MasterTransfer(id, &xfer) == I2C_STATUS_ARBLOST) {}
return len - xfer.txSz;
}
/* Transmit one byte and receive an array of bytes after a repeated start condition is generated in Master mode.
* This function is useful for communicating with the I2C slave registers
*/
int Chip_I2C_MasterCmdRead(I2C_ID_T id, uint8_t slaveAddr, uint8_t cmd, uint8_t *buff, int len)
{
I2C_XFER_T xfer = {0};
xfer.slaveAddr = slaveAddr;
xfer.txBuff = &cmd;
xfer.txSz = 1;
xfer.rxBuff = buff;
xfer.rxSz = len;
while (Chip_I2C_MasterTransfer(id, &xfer) == I2C_STATUS_ARBLOST) {}
return len - xfer.rxSz;
}
/* Sequential master read */
int Chip_I2C_MasterRead(I2C_ID_T id, uint8_t slaveAddr, uint8_t *buff, int len)
{
I2C_XFER_T xfer = {0};
xfer.slaveAddr = slaveAddr;
xfer.rxBuff = buff;
xfer.rxSz = len;
while (Chip_I2C_MasterTransfer(id, &xfer) == I2C_STATUS_ARBLOST) {}
return len - xfer.rxSz;
}
/* Check if master state is active */
int Chip_I2C_IsMasterActive(I2C_ID_T id)
{
return isMasterState(i2c[id].ip);
}
/* State change handler for master transfer */
void Chip_I2C_MasterStateHandler(I2C_ID_T id)
{
if (!handleMasterXferState(i2c[id].ip, i2c[id].mXfer)) {
i2c[id].mEvent(id, I2C_EVENT_DONE);
}
}
/* Setup slave function */
void Chip_I2C_SlaveSetup(I2C_ID_T id,
I2C_SLAVE_ID sid,
I2C_XFER_T *xfer,
I2C_EVENTHANDLER_T event,
uint8_t addrMask)
{
struct i2c_interface *iic = &i2c[id];
struct i2c_slave_interface *si2c = &i2c_slave[id][sid];
si2c->xfer = xfer;
si2c->event = event;
/* Set up the slave address */
if (sid != I2C_SLAVE_GENERAL) {
setSlaveAddr(iic->ip, sid, xfer->slaveAddr, addrMask);
}
if (!SLAVE_ACTIVE(iic) && !iic->mXfer) {
startSlaverXfer(iic->ip);
}
iic->flags |= 1 << (sid + 8);
}
/* I2C Slave event handler */
void Chip_I2C_SlaveStateHandler(I2C_ID_T id)
{
int ret;
struct i2c_interface *iic = &i2c[id];
/* Get the currently addressed slave */
if (!iic->sXfer) {
struct i2c_slave_interface *si2c;
I2C_SLAVE_ID sid = getSlaveIndex(iic->ip);
si2c = &i2c_slave[id][sid];
iic->sXfer = si2c->xfer;
iic->sEvent = si2c->event;
}
iic->sXfer->slaveAddr |= iic->mXfer != 0;
ret = handleSlaveXferState(iic->ip, iic->sXfer);
if (ret) {
if (iic->sXfer->status == I2C_STATUS_DONE) {
iic->sXfer = 0;
}
iic->sEvent(id, (I2C_EVENT_T) ret);
}
}
/* Disable I2C device */
void Chip_I2C_Disable(I2C_ID_T id)
{
LPC_I2Cx(id)->CONCLR = I2C_I2CONCLR_I2ENC;
}
/* State change checking */
int Chip_I2C_IsStateChanged(I2C_ID_T id)
{
return (LPC_I2Cx(id)->CONSET & I2C_CON_SI) != 0;
}

View File

@@ -0,0 +1,259 @@
/*
* @brief LPC13xx I2C master driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Control flags */
#define I2C_CON_FLAGS (I2C_CON_AA | I2C_CON_SI | I2C_CON_STO | I2C_CON_STA)
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initializes the LPC_I2C peripheral with specified parameter */
void Chip_I2CM_Init(LPC_I2C_T *pI2C)
{
/* Enable I2C clock */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C);
/* Peripheral reset control to I2C */
Chip_SYSCTL_PeriphReset(RESET_I2C0);
}
/* De-initializes the I2C peripheral registers to their default reset values */
void Chip_I2CM_DeInit(LPC_I2C_T *pI2C)
{
/* Disable I2C clock */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_I2C);
}
/* Set up bus speed for LPC_I2C interface */
void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed)
{
uint32_t clockDiv = (Chip_Clock_GetMainClockRate() / busSpeed);
Chip_I2CM_SetDutyCycle(pI2C, (clockDiv >> 1), (clockDiv - (clockDiv >> 1)));
}
/* Master transfer state change handler handler */
uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
uint32_t cclr = I2C_CON_FLAGS;
switch (Chip_I2CM_GetCurState(pI2C)) {
case 0x08: /* Start condition on bus */
case 0x10: /* Repeated start condition */
pI2C->DAT = (xfer->slaveAddr << 1) | (xfer->txSz == 0);
break;
/* Tx handling */
case 0x20: /* SLA+W sent NAK received */
case 0x30: /* DATA sent NAK received */
if ((xfer->options & I2CM_XFER_OPTION_IGNORE_NACK) == 0) {
xfer->status = I2CM_STATUS_NAK;
cclr &= ~I2C_CON_STO;
break;
}
case 0x18: /* SLA+W sent and ACK received */
case 0x28: /* DATA sent and ACK received */
if (!xfer->txSz) {
if (xfer->rxSz) {
cclr &= ~I2C_CON_STA;
}
else {
xfer->status = I2CM_STATUS_OK;
cclr &= ~I2C_CON_STO;
}
}
else {
pI2C->DAT = *xfer->txBuff++;
xfer->txSz--;
}
break;
/* Rx handling */
case 0x58: /* Data Received and NACK sent */
case 0x50: /* Data Received and ACK sent */
*xfer->rxBuff++ = pI2C->DAT;
xfer->rxSz--;
case 0x40: /* SLA+R sent and ACK received */
if ((xfer->rxSz > 1) || (xfer->options & I2CM_XFER_OPTION_LAST_RX_ACK)) {
cclr &= ~I2C_CON_AA;
}
if (xfer->rxSz == 0) {
xfer->status = I2CM_STATUS_OK;
cclr &= ~I2C_CON_STO;
}
break;
/* NAK Handling */
case 0x48: /* SLA+R sent NAK received */
xfer->status = I2CM_STATUS_SLAVE_NAK;
cclr &= ~I2C_CON_STO;
break;
case 0x38: /* Arbitration lost */
xfer->status = I2CM_STATUS_ARBLOST;
break;
case 0x00: /* Bus Error */
xfer->status = I2CM_STATUS_BUS_ERROR;
cclr &= ~I2C_CON_STO;
break;
default:
xfer->status = I2CM_STATUS_ERROR;
cclr &= ~I2C_CON_STO;
break;
}
/* Set clear control flags */
pI2C->CONSET = cclr ^ I2C_CON_FLAGS;
pI2C->CONCLR = cclr;
return xfer->status != I2CM_STATUS_BUSY;
}
/* Transmit and Receive data in master mode */
void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
/* set the transfer status as busy */
xfer->status = I2CM_STATUS_BUSY;
/* Clear controller state. */
Chip_I2CM_ResetControl(pI2C);
/* Enter to Master Transmitter mode */
Chip_I2CM_SendStart(pI2C);
}
/* Transmit and Receive data in master mode */
uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer)
{
uint32_t ret = 0;
/* start transfer */
Chip_I2CM_Xfer(pI2C, xfer);
while (ret == 0) {
/* wait for status change interrupt */
while ( Chip_I2CM_StateChanged(pI2C) == 0) {}
/* call state change handler */
ret = Chip_I2CM_XferHandler(pI2C, xfer);
}
return ret;
}
/* Master tx only */
uint32_t Chip_I2CM_Write(LPC_I2C_T *pI2C, const uint8_t *buff, uint32_t len)
{
uint32_t txLen = 0, err = 0;
/* clear state change interrupt status */
Chip_I2CM_ClearSI(pI2C);
/* generate START condition */
Chip_I2CM_SendStart(pI2C);
while ((txLen < len) && (err == 0)) {
/* wait for status change interrupt */
while ( Chip_I2CM_StateChanged(pI2C) == 0) {}
/* check status and send data */
switch (Chip_I2CM_GetCurState(pI2C)) {
case 0x08: /* Start condition on bus */
case 0x10: /* Repeated start condition */
case 0x18: /* SLA+W sent and ACK received */
case 0x28: /* DATA sent and ACK received */
Chip_I2CM_WriteByte(pI2C, buff[txLen++]);
break;
case 0x38: /* Arbitration lost */
break;
default: /* we shouldn't be in any other state */
err = 1;
break;
}
/* clear state change interrupt status */
Chip_I2CM_ClearSI(pI2C);
}
return txLen;
}
/* Sequential master read */
uint32_t Chip_I2CM_Read(LPC_I2C_T *pI2C, uint8_t *buff, uint32_t len)
{
uint32_t rxLen = 0, err = 0;
/* clear state change interrupt status */
Chip_I2CM_ClearSI(pI2C);
/* generate START condition and auto-ack data received */
pI2C->CONSET = I2C_CON_AA | I2C_CON_STA;
while ((rxLen < len) && (err == 0)) {
/* wait for status change interrupt */
while ( Chip_I2CM_StateChanged(pI2C) == 0) {}
/* check status and send data */
switch (Chip_I2CM_GetCurState(pI2C)) {
case 0x08: /* Start condition on bus */
case 0x10: /* Repeated start condition */
case 0x40: /* SLA+R sent and ACK received */
case 0x50: /* Data Received and ACK sent */
buff[rxLen++] = Chip_I2CM_ReadByte(pI2C);
break;
case 0x38: /* Arbitration lost */
break;
default: /* we shouldn't be in any other state */
err = 1;
break;
}
/* clear state change interrupt status */
Chip_I2CM_ClearSI(pI2C);
}
return rxLen;
}

View File

@@ -0,0 +1,59 @@
/*
* @brief LPC13xx IOCON driver
*
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
#if defined(CHIP_LPC1347)
/* I/O Control pin mux */
void Chip_IOCON_PinMuxSet(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin, uint32_t modefunc)
{
if (port == 0) {
pIOCON->PIO0[pin] = modefunc;
}
else {
pIOCON->PIO1[pin] = modefunc;
}
}
#endif

View File

@@ -0,0 +1,53 @@
/*
* @brief LPC11xx Pin Interrupt and Pattern Match driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#if defined(CHIP_LPC1347)
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
#endif /* defined(CHIP_LPC1347) */

View File

@@ -0,0 +1,114 @@
/*
* @brief LPC13xx PMU chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Enter MCU Sleep mode */
void Chip_PMU_SleepState(LPC_PMU_T *pPMU)
{
pPMU->PCON = PMU_PCON_PM_SLEEP;
SCB->SCR &= ~(1UL << SCB_SCR_SLEEPDEEP_Pos);
/* Enter sleep mode */
__WFI();
}
/* Enter MCU Deep Sleep mode */
void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU)
{
#if defined(CHIP_LPC1347)
pPMU->PCON = PMU_PCON_PM_DEEPSLEEP;
#elif defined(CHIP_LPC1343)
pPMU->PCON = PMU_PCON_PM_SLEEP;
#endif
SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos);
/* Enter sleep mode */
__WFI();
}
/* Enter MCU Power down mode */
#if defined(CHIP_LPC1347)
void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU)
{
SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos);
pPMU->PCON = PMU_PCON_PM_POWERDOWN;
/* Enter sleep mode */
__WFI();
}
#endif
/* Enter MCU Deep Power down mode */
void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU)
{
SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos);
pPMU->PCON = PMU_PCON_PM_DEEPPOWERDOWN;
/* Enter sleep mode */
__WFI();
}
/* Put some of the peripheral in sleep mode */
void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode)
{
if (SleepMode == PMU_MCU_DEEP_SLEEP) {
Chip_PMU_DeepSleepState(pPMU);
}
#if defined(CHIP_LPC1347)
else if (SleepMode == PMU_MCU_POWER_DOWN) {
Chip_PMU_PowerDownState(pPMU);
}
#endif
else if (SleepMode == PMU_MCU_DEEP_PWRDOWN) {
Chip_PMU_DeepPowerDownState(pPMU);
}
else {
/* PMU_MCU_SLEEP */
Chip_PMU_SleepState(pPMU);
}
}

View File

@@ -0,0 +1,167 @@
/*
* @brief Common ring buffer support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include <string.h>
#include "ring_buffer.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#define RB_INDH(rb) ((rb)->head & ((rb)->count - 1))
#define RB_INDT(rb) ((rb)->tail & ((rb)->count - 1))
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize ring buffer */
int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count)
{
RingBuff->data = buffer;
RingBuff->count = count;
RingBuff->itemSz = itemSize;
RingBuff->head = RingBuff->tail = 0;
return 1;
}
/* Insert a single item into Ring Buffer */
int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data)
{
uint8_t *ptr = RingBuff->data;
/* We cannot insert when queue is full */
if (RingBuffer_IsFull(RingBuff))
return 0;
ptr += RB_INDH(RingBuff) * RingBuff->itemSz;
memcpy(ptr, data, RingBuff->itemSz);
RingBuff->head++;
return 1;
}
/* Insert multiple items into Ring Buffer */
int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num)
{
uint8_t *ptr = RingBuff->data;
int cnt1, cnt2;
/* We cannot insert when queue is full */
if (RingBuffer_IsFull(RingBuff))
return 0;
/* Calculate the segment lengths */
cnt1 = cnt2 = RingBuffer_GetFree(RingBuff);
if (RB_INDH(RingBuff) + cnt1 >= RingBuff->count)
cnt1 = RingBuff->count - RB_INDH(RingBuff);
cnt2 -= cnt1;
cnt1 = MIN(cnt1, num);
num -= cnt1;
cnt2 = MIN(cnt2, num);
num -= cnt2;
/* Write segment 1 */
ptr += RB_INDH(RingBuff) * RingBuff->itemSz;
memcpy(ptr, data, cnt1 * RingBuff->itemSz);
RingBuff->head += cnt1;
/* Write segment 2 */
ptr = (uint8_t *) RingBuff->data + RB_INDH(RingBuff) * RingBuff->itemSz;
data = (const uint8_t *) data + cnt1 * RingBuff->itemSz;
memcpy(ptr, data, cnt2 * RingBuff->itemSz);
RingBuff->head += cnt2;
return cnt1 + cnt2;
}
/* Pop single item from Ring Buffer */
int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data)
{
uint8_t *ptr = RingBuff->data;
/* We cannot pop when queue is empty */
if (RingBuffer_IsEmpty(RingBuff))
return 0;
ptr += RB_INDT(RingBuff) * RingBuff->itemSz;
memcpy(data, ptr, RingBuff->itemSz);
RingBuff->tail++;
return 1;
}
/* Pop multiple items from Ring buffer */
int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num)
{
uint8_t *ptr = RingBuff->data;
int cnt1, cnt2;
/* We cannot insert when queue is empty */
if (RingBuffer_IsEmpty(RingBuff))
return 0;
/* Calculate the segment lengths */
cnt1 = cnt2 = RingBuffer_GetCount(RingBuff);
if (RB_INDT(RingBuff) + cnt1 >= RingBuff->count)
cnt1 = RingBuff->count - RB_INDT(RingBuff);
cnt2 -= cnt1;
cnt1 = MIN(cnt1, num);
num -= cnt1;
cnt2 = MIN(cnt2, num);
num -= cnt2;
/* Write segment 1 */
ptr += RB_INDT(RingBuff) * RingBuff->itemSz;
memcpy(data, ptr, cnt1 * RingBuff->itemSz);
RingBuff->tail += cnt1;
/* Write segment 2 */
ptr = (uint8_t *) RingBuff->data + RB_INDT(RingBuff) * RingBuff->itemSz;
data = (uint8_t *) data + cnt1 * RingBuff->itemSz;
memcpy(data, ptr, cnt2 * RingBuff->itemSz);
RingBuff->tail += cnt2;
return cnt1 + cnt2;
}

View File

@@ -0,0 +1,99 @@
/*
* @brief LPC13xx RITimer chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#if defined(CHIP_LPC1347)
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the RIT */
void Chip_RIT_Init(LPC_RITIMER_T *pRITimer)
{
pRITimer->COMPVAL = 0xFFFFFFFF;
pRITimer->MASK = 0x00000000;
pRITimer->CTRL = 0x0C;
pRITimer->COUNTER = 0x00000000;
pRITimer->COMPVAL_H = 0x0;
}
/* DeInitialize the RIT */
void Chip_RIT_DeInit(LPC_RITIMER_T *pRITimer)
{
Chip_RIT_Init(pRITimer);
}
/* Set timer interval value */
void Chip_RIT_SetTimerInterval(LPC_RITIMER_T *pRITimer, uint32_t time_interval)
{
uint32_t cmp_value;
/* Determine aapproximate compare value based on clock rate and passed interval */
cmp_value = (Chip_Clock_GetSystemClockRate() / 1000) * time_interval;
/* Set timer compare value */
Chip_RIT_SetCOMPVAL(pRITimer, cmp_value);
/* Set timer enable clear bit to clear timer to 0 whenever
counter value equals the contents of RICOMPVAL */
Chip_RIT_EnableCTRL(pRITimer, RIT_CTRL_ENCLR);
}
/* Check whether interrupt is pending */
IntStatus Chip_RIT_GetIntStatus(LPC_RITIMER_T *pRITimer)
{
uint8_t result;
if ((pRITimer->CTRL & RIT_CTRL_INT) == 1) {
result = SET;
}
else {
return RESET;
}
return (IntStatus) result;
}
#endif /* defined(CHIP_LPC1347) */

View File

@@ -0,0 +1,496 @@
/*
* @brief LPC13xx SSP Registers and control functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
STATIC void SSP_Write2BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
if (xf_setup->tx_data) {
Chip_SSP_SendFrame(pSSP, (*(uint16_t *) ((uint32_t) xf_setup->tx_data +
xf_setup->tx_cnt)));
}
else {
Chip_SSP_SendFrame(pSSP, 0xFFFF);
}
xf_setup->tx_cnt += 2;
}
/** SSP macro: write 1 bytes to FIFO buffer */
STATIC void SSP_Write1BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
if (xf_setup->tx_data) {
Chip_SSP_SendFrame(pSSP, (*(uint8_t *) ((uint32_t) xf_setup->tx_data + xf_setup->tx_cnt)));
}
else {
Chip_SSP_SendFrame(pSSP, 0xFF);
}
xf_setup->tx_cnt++;
}
/** SSP macro: read 1 bytes from FIFO buffer */
STATIC void SSP_Read2BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
uint16_t rDat;
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
(xf_setup->rx_cnt < xf_setup->length)) {
rDat = Chip_SSP_ReceiveFrame(pSSP);
if (xf_setup->rx_data) {
*(uint16_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
}
xf_setup->rx_cnt += 2;
}
}
/** SSP macro: read 2 bytes from FIFO buffer */
STATIC void SSP_Read1BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
uint16_t rDat;
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
(xf_setup->rx_cnt < xf_setup->length)) {
rDat = Chip_SSP_ReceiveFrame(pSSP);
if (xf_setup->rx_data) {
*(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
}
xf_setup->rx_cnt++;
}
}
/* Returns clock for the peripheral block */
STATIC CHIP_SYSCTL_CLOCK_T Chip_SSP_GetClockIndex(LPC_SSP_T *pSSP)
{
CHIP_SYSCTL_CLOCK_T clkSSP;
if (pSSP == LPC_SSP0) {
clkSSP = SYSCTL_CLOCK_SSP0;
}
else {
clkSSP = SYSCTL_CLOCK_SSP1;
}
return clkSSP;
}
/* Returns reset ID for the peripheral block */
STATIC CHIP_SYSCTL_PERIPH_RESET_T Chip_SSP_GetResetIndex(LPC_SSP_T *pSSP)
{
CHIP_SYSCTL_PERIPH_RESET_T resetSSP;
if (pSSP == LPC_SSP0) {
resetSSP = RESET_SSP0;
}
else {
resetSSP = RESET_SSP1;
}
return resetSSP;
}
/* Returns reset ID for the peripheral block */
STATIC void Chip_SSP_SetSSPClkDivider(LPC_SSP_T *pSSP, uint32_t div)
{
if (pSSP == LPC_SSP0) {
Chip_Clock_SetSSP0ClockDiv(div);
}
else {
Chip_Clock_SetSSP1ClockDiv(div);
}
}
/* Returns SSP peripheral clock for the peripheral block */
STATIC uint32_t Chip_SSP_GetPCLKkRate(LPC_SSP_T *pSSP)
{
uint32_t sspCLK = Chip_Clock_GetMainClockRate();
if (pSSP == LPC_SSP0) {
sspCLK /= Chip_Clock_GetSSP0ClockDiv();
}
else {
sspCLK /= Chip_Clock_GetSSP1ClockDiv();
}
return sspCLK;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/*Set up output clocks per bit for SSP bus*/
void Chip_SSP_SetClockRate(LPC_SSP_T *pSSP, uint32_t clk_rate, uint32_t prescale)
{
uint32_t temp;
temp = pSSP->CR0 & (~(SSP_CR0_SCR(0xFF)));
pSSP->CR0 = temp | (SSP_CR0_SCR(clk_rate));
pSSP->CPSR = prescale;
}
/* SSP Polling Read/Write in blocking mode */
uint32_t Chip_SSP_RWFrames_Blocking(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
/* Clear all remaining frames in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
Chip_SSP_ReceiveFrame(pSSP);
}
/* Clear status */
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
/* write data to buffer */
if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
SSP_Write2BFifo(pSSP, xf_setup);
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
SSP_Read2BFifo(pSSP, xf_setup);
}
}
else {
while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
/* write data to buffer */
if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
SSP_Write1BFifo(pSSP, xf_setup);
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
SSP_Read1BFifo(pSSP, xf_setup);
}
}
if (xf_setup->tx_data) {
return xf_setup->tx_cnt;
}
else if (xf_setup->rx_data) {
return xf_setup->rx_cnt;
}
return 0;
}
/* SSP Polling Write in blocking mode */
uint32_t Chip_SSP_WriteFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
{
uint32_t tx_cnt = 0, rx_cnt = 0;
/* Clear all remaining frames in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
Chip_SSP_ReceiveFrame(pSSP);
}
/* Clear status */
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
uint16_t *wdata16;
wdata16 = (uint16_t *) buffer;
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
/* write data to buffer */
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
Chip_SSP_SendFrame(pSSP, *wdata16);
wdata16++;
tx_cnt += 2;
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
rx_cnt += 2;
}
}
}
else {
uint8_t *wdata8;
wdata8 = buffer;
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
/* write data to buffer */
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
Chip_SSP_SendFrame(pSSP, *wdata8);
wdata8++;
tx_cnt++;
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
rx_cnt++;
}
}
}
return tx_cnt;
}
/* SSP Polling Read in blocking mode */
uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
{
uint32_t rx_cnt = 0, tx_cnt = 0;
/* Clear all remaining frames in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
Chip_SSP_ReceiveFrame(pSSP);
}
/* Clear status */
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
uint16_t *rdata16;
rdata16 = (uint16_t *) buffer;
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
/* write data to buffer */
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
Chip_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
tx_cnt += 2;
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
*rdata16 = Chip_SSP_ReceiveFrame(pSSP);
rdata16++;
rx_cnt += 2;
}
}
}
else {
uint8_t *rdata8;
rdata8 = buffer;
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
/* write data to buffer */
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
Chip_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
tx_cnt++;
}
/* Check overrun error */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
*rdata8 = Chip_SSP_ReceiveFrame(pSSP);
rdata8++;
rx_cnt++;
}
}
}
return rx_cnt;
}
/* Clean all data in RX FIFO of SSP */
void Chip_SSP_Int_FlushData(LPC_SSP_T *pSSP)
{
if (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {}
}
/* Clear all remaining frames in RX FIFO */
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
Chip_SSP_ReceiveFrame(pSSP);
}
/* Clear status */
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
}
/* SSP Interrupt Read/Write with 8-bit frame width */
Status Chip_SSP_Int_RWFrames8Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
/* Check overrun error in RIS register */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
/* check if RX FIFO contains data */
SSP_Read1BFifo(pSSP, xf_setup);
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
/* Write data to buffer */
SSP_Write1BFifo(pSSP, xf_setup);
/* Check overrun error in RIS register */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
SSP_Read1BFifo(pSSP, xf_setup);
}
return SUCCESS;
}
return ERROR;
}
/* SSP Interrupt Read/Write with 16-bit frame width */
Status Chip_SSP_Int_RWFrames16Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
{
/* Check overrun error in RIS register */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
/* check if RX FIFO contains data */
SSP_Read2BFifo(pSSP, xf_setup);
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
/* Write data to buffer */
SSP_Write2BFifo(pSSP, xf_setup);
/* Check overrun error in RIS register */
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
return ERROR;
}
/* Check for any data available in RX FIFO */
SSP_Read2BFifo(pSSP, xf_setup);
}
return SUCCESS;
}
return ERROR;
}
/* Set the SSP operating modes, master or slave */
void Chip_SSP_SetMaster(LPC_SSP_T *pSSP, bool master)
{
if (master) {
Chip_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
}
else {
Chip_SSP_Set_Mode(pSSP, SSP_MODE_SLAVE);
}
}
/* Set the clock frequency for SSP interface */
void Chip_SSP_SetBitRate(LPC_SSP_T *pSSP, uint32_t bitRate)
{
uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
ssp_clk = Chip_SSP_GetPCLKkRate(pSSP);
cr0_div = 0;
cmp_clk = 0xFFFFFFFF;
prescale = 2;
while (cmp_clk > bitRate) {
cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
if (cmp_clk > bitRate) {
cr0_div++;
if (cr0_div > 0xFF) {
cr0_div = 0;
prescale += 2;
}
}
}
Chip_SSP_SetClockRate(pSSP, cr0_div, prescale);
}
/* Initialize the SSP */
void Chip_SSP_Init(LPC_SSP_T *pSSP)
{
Chip_Clock_EnablePeriphClock(Chip_SSP_GetClockIndex(pSSP));
Chip_SSP_SetSSPClkDivider(pSSP, 1);
Chip_SYSCTL_PeriphReset(Chip_SSP_GetResetIndex(pSSP));
Chip_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
Chip_SSP_SetFormat(pSSP, SSP_BITS_8, SSP_FRAMEFORMAT_SPI, SSP_CLOCK_CPHA0_CPOL0);
Chip_SSP_SetBitRate(pSSP, 100000);
}
/* De-initializes the SSP peripheral */
void Chip_SSP_DeInit(LPC_SSP_T *pSSP)
{
Chip_SSP_Disable(pSSP);
Chip_Clock_DisablePeriphClock(Chip_SSP_GetClockIndex(pSSP));
Chip_SSP_SetSSPClkDivider(pSSP, 0);
}

View File

@@ -0,0 +1,108 @@
/*
* @brief LPC13xx specific stopwatch implementation
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
#include "stopwatch.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* Precompute these to optimize runtime */
static uint32_t ticksPerSecond;
static uint32_t ticksPerMs;
static uint32_t ticksPerUs;
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize stopwatch */
void StopWatch_Init(void)
{
/* Use timer 1. Set prescaler to divide by 8, should give ticks at 9 MHz.
That gives a useable stopwatch measurement range of about 8 minutes
(if system clock is running at 72 MHz). */
const uint32_t prescaleDivisor = 8;
Chip_TIMER_Init(LPC_TIMER32_1);
Chip_TIMER_PrescaleSet(LPC_TIMER32_1, prescaleDivisor - 1);
Chip_TIMER_Enable(LPC_TIMER32_1);
/* Pre-compute tick rate. */
ticksPerSecond = Chip_Clock_GetSystemClockRate() / prescaleDivisor;
ticksPerMs = ticksPerSecond / 1000;
ticksPerUs = ticksPerSecond / 1000000;
}
/* Start a stopwatch */
uint32_t StopWatch_Start(void)
{
/* Return the current timer count. */
return Chip_TIMER_ReadCount(LPC_TIMER32_1);
}
/* Returns number of ticks per second of the stopwatch timer */
uint32_t StopWatch_TicksPerSecond(void)
{
return ticksPerSecond;
}
/* Converts from stopwatch ticks to mS. */
uint32_t StopWatch_TicksToMs(uint32_t ticks)
{
return ticks / ticksPerMs;
}
/* Converts from stopwatch ticks to uS. */
uint32_t StopWatch_TicksToUs(uint32_t ticks)
{
return ticks / ticksPerUs;
}
/* Converts from mS to stopwatch ticks. */
uint32_t StopWatch_MsToTicks(uint32_t mS)
{
return mS * ticksPerMs;
}
/* Converts from uS to stopwatch ticks. */
uint32_t StopWatch_UsToTicks(uint32_t uS)
{
return uS * ticksPerUs;
}

View File

@@ -0,0 +1,110 @@
/*
* @brief LPC13xx System Control functions
*
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* PDSLEEPCFG register mask */
#if defined(CHIP_LPC1343)
#if defined(CHIP_LPC1300L)
#define PDSLEEPUSEMASK 0x000018B7 /* For CHIP_LPC1300L only */
#else
#define PDSLEEPUSEMASK 0x00000FB7
#endif /* defined (CHIP_LPC1300L) */
#else
#define PDSLEEPUSEMASK 0x00000007
#endif /* defined(CHIP_LPC1343) */
#define PDSLEEPMASKTMP (SYSCTL_DEEPSLP_BOD_PD | SYSCTL_DEEPSLP_WDTOSC_PD)
#define PDSLEEPMASK ((PDSLEEPUSEMASK) &~(PDSLEEPMASKTMP))
/* PDWAKECFG register mask */
#if defined(CHIP_LPC1347)
#define PDWAKEUPUSEMASK 0x00000800
#else
#define PDWAKEUPUSEMASK 0x0000F800
#endif
#define PDWAKEUPMASKTMP 0x000005FF
/* PDRUNCFG register mask */
#if defined(CHIP_LPC1347)
#define PDRUNCFGUSEMASK 0x0000E800
#else
#define PDRUNCFGUSEMASK 0x0000F800
#endif
#define PDRUNCFGMASKTMP 0x000005FF
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Setup deep sleep behaviour for power down */
void Chip_SYSCTL_SetDeepSleepPD(uint32_t sleepmask)
{
/* Update new value */
LPC_SYSCTL->PDSLEEPCFG = PDSLEEPMASK | (sleepmask & PDSLEEPMASKTMP);
}
/* Setup wakeup behaviour from deep sleep */
void Chip_SYSCTL_SetWakeup(uint32_t wakeupmask)
{
/* Update new value */
LPC_SYSCTL->PDWAKECFG = PDWAKEUPUSEMASK | (wakeupmask & PDWAKEUPMASKTMP);
}
/* Power down one or more blocks or peripherals */
void Chip_SYSCTL_PowerDown(uint32_t powerdownmask)
{
uint32_t pdrun;
pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP;
pdrun |= (powerdownmask & PDRUNCFGMASKTMP);
LPC_SYSCTL->PDRUNCFG = (pdrun | PDRUNCFGUSEMASK);
}
/* Power up one or more blocks or peripherals */
void Chip_SYSCTL_PowerUp(uint32_t powerupmask)
{
uint32_t pdrun;
pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP;
pdrun &= ~(powerupmask & PDRUNCFGMASKTMP);
LPC_SYSCTL->PDRUNCFG = (pdrun | PDRUNCFGUSEMASK);
}

View File

@@ -0,0 +1,132 @@
/*
* @brief LPC13xx Chip specific SystemInit
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Setup system clocking */
void Chip_SetupXtalClocking(void)
{
volatile int i;
/* Powerup main oscillator */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSOSC_PD);
/* Wait an estimated 200us for OSC to be stablized, no status
indication, dummy wait */
for (i = 0; i < 0x200; i++) {}
/* Set system PLL input to main oscillator */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_SYSOSC);
/* Power down PLL to change the PLL divider ratio */
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz
MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2)
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz
FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range) */
Chip_Clock_SetupSystemPLL(5, 1);
/* Powerup system PLL */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);
/* Wait for PLL to lock */
while (!Chip_Clock_IsSystemPLLLocked()) {}
/* Set system clock divider to 1 */
Chip_Clock_SetSysClockDiv(1);
/* Setup FLASH access to 3 clocks (72MHz clock) */
Chip_FMC_SetFLASHAccess(FLASHTIM_72MHZ_CPU);
/* Set main clock source to the system PLL. This will drive 72MHz
for the main clock and 72MHz for the system clock */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
}
/* Set up and initialize hardware prior to call to main */
void Chip_SetupIrcClocking(void)
{
/* IRC should be powered up */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRC_PD);
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRCOUT_PD);
/* Set system PLL input to main oscillator */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);
/* Power down PLL to change the PLL divider ratio */
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz
MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2)
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz
FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range) */
Chip_Clock_SetupSystemPLL(5, 1);
/* Powerup system PLL */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);
/* Wait for PLL to lock */
while (!Chip_Clock_IsSystemPLLLocked()) {}
/* Set system clock divider to 1 */
Chip_Clock_SetSysClockDiv(1);
/* Setup FLASH access to 3 clocks */
Chip_FMC_SetFLASHAccess(FLASHTIM_72MHZ_CPU);
/* Set main clock source to the system PLL. This will drive 48MHz
for the main clock and 48MHz for the system clock */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
}
/* Set up and initialize hardware prior to call to main */
void Chip_SystemInit(void)
{
/* Initial internal clocking */
Chip_SetupIrcClocking();
}

View File

@@ -0,0 +1,115 @@
/*
* @brief LPC13xx 16/32-bit Timer/PWM control functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/* Returns clock index for a specific timer referenced by IP block address */
STATIC CHIP_SYSCTL_CLOCK_T Chip_TIMER_GetClock(LPC_TIMER_T *pTMR)
{
CHIP_SYSCTL_CLOCK_T tmrClk;
if (pTMR == LPC_TIMER32_1) {
tmrClk = SYSCTL_CLOCK_CT32B1;
}
else if (pTMR == LPC_TIMER16_0) {
tmrClk = SYSCTL_CLOCK_CT16B0;
}
else if (pTMR == LPC_TIMER16_1) {
tmrClk = SYSCTL_CLOCK_CT16B1;
}
else {
tmrClk = SYSCTL_CLOCK_CT32B0;
}
return tmrClk;
}
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize a timer */
void Chip_TIMER_Init(LPC_TIMER_T *pTMR)
{
Chip_Clock_EnablePeriphClock(Chip_TIMER_GetClock(pTMR));
}
/* Shutdown a timer */
void Chip_TIMER_DeInit(LPC_TIMER_T *pTMR)
{
Chip_Clock_DisablePeriphClock(Chip_TIMER_GetClock(pTMR));
}
/* Resets the timer terminal and prescale counts to 0 */
void Chip_TIMER_Reset(LPC_TIMER_T *pTMR)
{
uint32_t reg;
/* Disable timer, set terminal count to non-0 */
reg = pTMR->TCR;
pTMR->TCR = 0;
pTMR->TC = 1;
/* Reset timer counter */
pTMR->TCR = TIMER_RESET;
/* Wait for terminal count to clear */
while (pTMR->TC != 0) {}
/* Restore timer state */
pTMR->TCR = reg;
}
/* Sets external match control (MATn.matchnum) pin control */
void Chip_TIMER_ExtMatchControlSet(LPC_TIMER_T *pTMR, int8_t initial_state,
TIMER_PIN_MATCH_STATE_T matchState, int8_t matchnum)
{
uint32_t mask, reg;
/* Clear bits corresponding to selected match register */
mask = (1 << matchnum) | (0x03 << (4 + (matchnum * 2)));
reg = pTMR->EMR &= ~mask;
/* Set new configuration for selected match register */
pTMR->EMR = reg | (((uint32_t) initial_state) << matchnum) |
(((uint32_t) matchState) << (4 + (matchnum * 2)));
}

View File

@@ -0,0 +1,280 @@
/*
* @brief LPC13xx UART chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initializes the pUART peripheral */
void Chip_UART_Init(LPC_USART_T *pUART)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_UART0);
Chip_Clock_SetUARTClockDiv(1);
/* Enable FIFOs by default, reset them */
Chip_UART_SetupFIFOS(pUART, (UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS));
/* Default 8N1, with DLAB disabled */
Chip_UART_ConfigData(pUART, (UART_LCR_WLEN8 | UART_LCR_SBS_1BIT | UART_LCR_PARITY_DIS));
/* Disable fractional divider */
pUART->FDR = 0x10;
}
/* De-initializes the pUART peripheral */
void Chip_UART_DeInit(LPC_USART_T *pUART)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_UART0);
}
/* Transmit a byte array through the UART peripheral (non-blocking) */
int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes)
{
int sent = 0;
uint8_t *p8 = (uint8_t *) data;
/* Send until the transmit FIFO is full or out of bytes */
while ((sent < numBytes) &&
((Chip_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0)) {
Chip_UART_SendByte(pUART, *p8);
p8++;
sent++;
}
return sent;
}
/* Transmit a byte array through the UART peripheral (blocking) */
int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
{
int pass, sent = 0;
uint8_t *p8 = (uint8_t *) data;
while (numBytes > 0) {
pass = Chip_UART_Send(pUART, p8, numBytes);
numBytes -= pass;
sent += pass;
p8 += pass;
}
return sent;
}
/* Read data through the UART peripheral (non-blocking) */
int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes)
{
int readBytes = 0;
uint8_t *p8 = (uint8_t *) data;
/* Send until the transmit FIFO is full or out of bytes */
while ((readBytes < numBytes) &&
((Chip_UART_ReadLineStatus(pUART) & UART_LSR_RDR) != 0)) {
*p8 = Chip_UART_ReadByte(pUART);
p8++;
readBytes++;
}
return readBytes;
}
/* Read data through the UART peripheral (blocking) */
int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes)
{
int pass, readBytes = 0;
uint8_t *p8 = (uint8_t *) data;
while (readBytes < numBytes) {
pass = Chip_UART_Read(pUART, p8, numBytes);
numBytes -= pass;
readBytes += pass;
p8 += pass;
}
return readBytes;
}
/* Determines and sets best dividers to get a target bit rate */
uint32_t Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate)
{
uint32_t div, divh, divl, clkin;
/* Determine UART clock in rate without FDR */
clkin = Chip_Clock_GetMainClockRate();
div = clkin / (baudrate * 16);
/* High and low halves of the divider */
divh = div / 256;
divl = div - (divh * 256);
Chip_UART_EnableDivisorAccess(pUART);
Chip_UART_SetDivisorLatches(pUART, divl, divh);
Chip_UART_DisableDivisorAccess(pUART);
/* Fractional FDR alreadt setup for 1 in UART init */
return clkin / div;
}
/* UART receive-only interrupt handler for ring buffers */
void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
{
/* New data will be ignored if data not popped in time */
while (Chip_UART_ReadLineStatus(pUART) & UART_LSR_RDR) {
uint8_t ch = Chip_UART_ReadByte(pUART);
RingBuffer_Insert(pRB, &ch);
}
}
/* UART transmit-only interrupt handler for ring buffers */
void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
{
uint8_t ch;
/* Fill FIFO until full or until TX ring buffer is empty */
while ((Chip_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0 &&
RingBuffer_Pop(pRB, &ch)) {
Chip_UART_SendByte(pUART, ch);
}
}
/* Populate a transmit ring buffer and start UART transmit */
uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int bytes)
{
uint32_t ret;
uint8_t *p8 = (uint8_t *) data;
/* Don't let UART transmit ring buffer change in the UART IRQ handler */
Chip_UART_IntDisable(pUART, UART_IER_THREINT);
/* Move as much data as possible into transmit ring buffer */
ret = RingBuffer_InsertMult(pRB, p8, bytes);
Chip_UART_TXIntHandlerRB(pUART, pRB);
/* Add additional data to transmit ring buffer if possible */
ret += RingBuffer_InsertMult(pRB, (p8 + ret), (bytes - ret));
/* Enable UART transmit interrupt */
Chip_UART_IntEnable(pUART, UART_IER_THREINT);
return ret;
}
/* Copy data from a receive ring buffer */
int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes)
{
(void) pUART;
return RingBuffer_PopMult(pRB, (uint8_t *) data, bytes);
}
/* UART receive/transmit interrupt handler for ring buffers */
void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
{
/* Handle transmit interrupt if enabled */
if (pUART->IER & UART_IER_THREINT) {
Chip_UART_TXIntHandlerRB(pUART, pTXRB);
/* Disable transmit interrupt if the ring buffer is empty */
if (RingBuffer_IsEmpty(pTXRB)) {
Chip_UART_IntDisable(pUART, UART_IER_THREINT);
}
}
/* Handle receive interrupt */
Chip_UART_RXIntHandlerRB(pUART, pRXRB);
}
/* Determines and sets best dividers to get a target baud rate */
uint32_t Chip_UART_SetBaudFDR(LPC_USART_T *pUART, uint32_t baudrate)
{
uint32_t uClk;
uint32_t dval, mval;
uint32_t dl;
uint32_t rate16 = 16 * baudrate;
uint32_t actualRate = 0;
/* Get Clock rate */
uClk = Chip_Clock_GetMainClockRate();
/* The fractional is calculated as (PCLK % (16 * Baudrate)) / (16 * Baudrate)
* Let's make it to be the ratio DivVal / MulVal
*/
dval = uClk % rate16;
/* The PCLK / (16 * Baudrate) is fractional
* => dval = pclk % rate16
* mval = rate16;
* now mormalize the ratio
* dval / mval = 1 / new_mval
* new_mval = mval / dval
* new_dval = 1
*/
if (dval > 0) {
mval = rate16 / dval;
dval = 1;
/* In case mval still bigger then 4 bits
* no adjustment require
*/
if (mval > 12) {
dval = 0;
}
}
dval &= 0xf;
mval &= 0xf;
dl = uClk / (rate16 + rate16 *dval / mval);
/* Update UART registers */
Chip_UART_EnableDivisorAccess(pUART);
Chip_UART_SetDivisorLatches(pUART, UART_LOAD_DLL(dl), UART_LOAD_DLM(dl));
Chip_UART_DisableDivisorAccess(pUART);
/* Set best fractional divider */
pUART->FDR = (UART_FDR_MULVAL(mval) | UART_FDR_DIVADDVAL(dval));
/* Return actual baud rate */
actualRate = uClk / (16 * dl + 16 * dl * dval / mval);
return actualRate;
}

View File

@@ -0,0 +1,80 @@
/*
* @brief LPC13xx WWDT chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "chip.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
/*****************************************************************************
* Public functions
****************************************************************************/
/* Initialize the Watchdog timer */
void Chip_WWDT_Init(LPC_WWDT_T *pWWDT)
{
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_WDT);
/* Disable watchdog */
pWWDT->MOD = 0;
pWWDT->TC = 0xFF;
#if defined(WATCHDOG_WINDOW_SUPPORT)
pWWDT->WARNINT = 0xFFFF;
pWWDT->WINDOW = 0xFFFFFF;
#endif
}
/* Shutdown the Watchdog timer */
void Chip_WWDT_DeInit(LPC_WWDT_T *pWWDT)
{
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_WDT);
}
/* Clear WWDT interrupt status flags */
void Chip_WWDT_ClearStatusFlag(LPC_WWDT_T *pWWDT, uint32_t status)
{
if (status & WWDT_WDMOD_WDTOF) {
pWWDT->MOD &= (~WWDT_WDMOD_WDTOF) & WWDT_WDMOD_BITMASK;
}
if (status & WWDT_WDMOD_WDINT) {
pWWDT->MOD |= WWDT_WDMOD_WDINT;
}
}