lpc13xx build ok (not work) with lpcopen
This commit is contained in:
287
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/adc_13xx.c
Normal file
287
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/adc_13xx.c
Normal 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;
|
||||
}
|
||||
|
||||
71
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/chip_13xx.c
Normal file
71
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/chip_13xx.c
Normal 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);
|
||||
}
|
||||
|
||||
261
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/clock_13xx.c
Normal file
261
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/clock_13xx.c
Normal 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;
|
||||
}
|
||||
82
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/flash_13xx.c
Normal file
82
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/flash_13xx.c
Normal 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);
|
||||
}
|
||||
108
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpio_13xx_1.c
Normal file
108
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpio_13xx_1.c
Normal 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) */
|
||||
140
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpio_13xx_2.c
Normal file
140
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpio_13xx_2.c
Normal 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) */
|
||||
52
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpiogroup_13xx.c
Normal file
52
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/gpiogroup_13xx.c
Normal 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) */
|
||||
548
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/i2c_13xx.c
Normal file
548
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/i2c_13xx.c
Normal 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;
|
||||
}
|
||||
259
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/i2cm_13xx.c
Normal file
259
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/i2cm_13xx.c
Normal 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;
|
||||
}
|
||||
59
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/iocon_13xx.c
Normal file
59
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/iocon_13xx.c
Normal 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
|
||||
53
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/pinint_13xx.c
Normal file
53
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/pinint_13xx.c
Normal 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) */
|
||||
|
||||
114
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/pmu_13xx.c
Normal file
114
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/pmu_13xx.c
Normal 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);
|
||||
}
|
||||
}
|
||||
167
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ring_buffer.c
Normal file
167
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ring_buffer.c
Normal 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;
|
||||
}
|
||||
99
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ritimer_13xx.c
Normal file
99
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ritimer_13xx.c
Normal 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) */
|
||||
496
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ssp_13xx.c
Normal file
496
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/ssp_13xx.c
Normal 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);
|
||||
}
|
||||
|
||||
108
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/stopwatch_13xx.c
Normal file
108
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/stopwatch_13xx.c
Normal 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;
|
||||
}
|
||||
110
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/sysctl_13xx.c
Normal file
110
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/sysctl_13xx.c
Normal 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);
|
||||
}
|
||||
132
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/sysinit_13xx.c
Normal file
132
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/sysinit_13xx.c
Normal 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();
|
||||
}
|
||||
115
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/timer_13xx.c
Normal file
115
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/timer_13xx.c
Normal 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)));
|
||||
}
|
||||
280
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/uart_13xx.c
Normal file
280
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/uart_13xx.c
Normal 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;
|
||||
}
|
||||
80
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/wwdt_13xx.c
Normal file
80
hw/mcu/nxp/lpc13xx/lpc_chip_13xx/src/wwdt_13xx.c
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user