add lpcopen lpc11u6x files
This commit is contained in:
209
hw/mcu/nxp/lpc_chip_11u6x/src/adc_11u6x.c
Normal file
209
hw/mcu/nxp/lpc_chip_11u6x/src/adc_11u6x.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* @brief LPC11u6x ADC 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
|
||||
****************************************************************************/
|
||||
|
||||
/* Set ADC interrupt bits (safe) */
|
||||
void Chip_ADC_SetIntBits(LPC_ADC_T *pADC, uint32_t intMask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pADC->INTEN & 0x07FFFFFF;
|
||||
|
||||
pADC->INTEN = temp | intMask;
|
||||
}
|
||||
|
||||
/* Clear ADC interrupt bits (safe) */
|
||||
void Chip_ADC_ClearIntBits(LPC_ADC_T *pADC, uint32_t intMask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pADC->INTEN & 0x07FFFFFF;
|
||||
|
||||
pADC->INTEN = temp & ~intMask;
|
||||
}
|
||||
|
||||
/* Set ADC threshold selection bits (safe) */
|
||||
void Chip_ADC_SetTHRSELBits(LPC_ADC_T *pADC, uint32_t mask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pADC->CHAN_THRSEL & 0x00000FFF;
|
||||
|
||||
pADC->CHAN_THRSEL = temp | mask;
|
||||
}
|
||||
|
||||
/* Clear ADC threshold selection bits (safe) */
|
||||
void Chip_ADC_ClearTHRSELBits(LPC_ADC_T *pADC, uint32_t mask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pADC->CHAN_THRSEL & 0x00000FFF;
|
||||
|
||||
pADC->CHAN_THRSEL = temp & ~mask;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize the ADC peripheral */
|
||||
void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags)
|
||||
{
|
||||
/* Power up ADC and enable ADC base clock */
|
||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC_PD);
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC);
|
||||
|
||||
/* Disable ADC interrupts */
|
||||
pADC->INTEN = 0;
|
||||
|
||||
/* Set ADC control options */
|
||||
pADC->CTRL = flags;
|
||||
}
|
||||
|
||||
/* Start ADC calibration */
|
||||
void Chip_ADC_StartCalibration(LPC_ADC_T *pADC)
|
||||
{
|
||||
uint32_t save_ADC_CTRL;
|
||||
|
||||
save_ADC_CTRL = pADC->CTRL;
|
||||
Chip_ADC_SetClockRate(LPC_ADC, ADC_CALIBRATE_RATE);
|
||||
|
||||
pADC->CTRL = (pADC->CTRL | ADC_CR_CALMODEBIT) & ~ADC_CR_LPWRMODEBIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start ADC calibration
|
||||
* @param pADC : The base of ADC peripheral on the chip
|
||||
* @return TRUE if calibration is complete, otherwise FALSE.
|
||||
*/
|
||||
bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC)
|
||||
{
|
||||
return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0);
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown ADC */
|
||||
void Chip_ADC_DeInit(LPC_ADC_T *pADC)
|
||||
{
|
||||
pADC->INTEN = 0;
|
||||
pADC->CTRL = 0;
|
||||
|
||||
/* Stop ADC clock and then power down ADC */
|
||||
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC);
|
||||
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC_PD);
|
||||
}
|
||||
|
||||
/* Set ADC clock rate */
|
||||
void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate)
|
||||
{
|
||||
Chip_ADC_SetDivider(pADC, ((Chip_Clock_GetSystemClockRate() + (rate>>2)) / rate) -1);
|
||||
}
|
||||
|
||||
/* Helper function for safely setting ADC sequencer register bits */
|
||||
void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read sequencer register and mask off bits 20..25 */
|
||||
temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
|
||||
|
||||
/* OR in passed bits */
|
||||
pADC->SEQ_CTRL[seqIndex] = temp | bits;
|
||||
}
|
||||
|
||||
/* Helper function for safely clearing ADC sequencer register bits */
|
||||
void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read sequencer register and mask off bits 20..25 */
|
||||
temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
|
||||
|
||||
/* OR in passed bits */
|
||||
pADC->SEQ_CTRL[seqIndex] = temp & ~bits;
|
||||
}
|
||||
|
||||
/* Enable interrupts in ADC (sequencers A/B and overrun) */
|
||||
void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask)
|
||||
{
|
||||
Chip_ADC_SetIntBits(pADC, intMask);
|
||||
}
|
||||
|
||||
/* Disable interrupts in ADC (sequencers A/B and overrun) */
|
||||
void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask)
|
||||
{
|
||||
Chip_ADC_ClearIntBits(pADC, intMask);
|
||||
}
|
||||
|
||||
/* Enable a threshold event interrupt in ADC */
|
||||
void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt)
|
||||
{
|
||||
int shiftIndex = 3 + (ch * 2);
|
||||
|
||||
/* Clear current bits first */
|
||||
Chip_ADC_ClearIntBits(pADC, (ADC_INTEN_CMP_MASK << shiftIndex));
|
||||
|
||||
/* Set new threshold interrupt type */
|
||||
Chip_ADC_SetIntBits(pADC, ((uint32_t) thInt << shiftIndex));
|
||||
}
|
||||
|
||||
/* Select threshold 0 values for comparison for selected channels */
|
||||
void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels)
|
||||
{
|
||||
Chip_ADC_ClearTHRSELBits(pADC, channels);
|
||||
}
|
||||
|
||||
/* Select threshold 1 value for comparison for selected channels */
|
||||
void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels)
|
||||
{
|
||||
Chip_ADC_SetTHRSELBits(pADC, channels);
|
||||
}
|
||||
84
hw/mcu/nxp/lpc_chip_11u6x/src/chip_11u6x.c
Normal file
84
hw/mcu/nxp/lpc_chip_11u6x/src/chip_11u6x.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* @brief LPC11u6x 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)
|
||||
{
|
||||
/* Set USB PLL input to main oscillator */
|
||||
Chip_Clock_SetUSBPLLSource(SYSCTL_USBPLLCLKSRC_MAINOSC);
|
||||
/* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz
|
||||
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
||||
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
||||
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
||||
Chip_Clock_SetupUSBPLL(3, 1);
|
||||
|
||||
/* Powerup USB PLL */
|
||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD);
|
||||
|
||||
/* Wait for PLL to lock */
|
||||
while (!Chip_Clock_IsUSBPLLLocked()) {}
|
||||
|
||||
/* enable USB main clock */
|
||||
Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1);
|
||||
/* Enable AHB clock to the USB block and USB RAM. */
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USBRAM);
|
||||
/* power UP USB Phy */
|
||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPAD_PD);
|
||||
}
|
||||
315
hw/mcu/nxp/lpc_chip_11u6x/src/clock_11u6x.c
Normal file
315
hw/mcu/nxp/lpc_chip_11u6x/src/clock_11u6x.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* @brief LPC11U6X System clock control functions
|
||||
*
|
||||
* @note
|
||||
* Copyright(C) NXP Semiconductors, 2013
|
||||
* 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 rate */
|
||||
STATIC uint32_t Chip_Clock_GetWDTRate(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
|
||||
****************************************************************************/
|
||||
|
||||
/* Get USART 1/2/3/4 UART base rate */
|
||||
uint32_t Chip_Clock_GetUSARTNBaseClockRate(void)
|
||||
{
|
||||
uint64_t inclk;
|
||||
uint32_t div;
|
||||
|
||||
div = (uint32_t) Chip_Clock_GetUSARTNBaseClockDiv();
|
||||
if (div == 0) {
|
||||
/* Divider is 0 so UART clock is disabled */
|
||||
inclk = 0;
|
||||
}
|
||||
else {
|
||||
uint32_t mult, divf;
|
||||
|
||||
/* Input clock into FRG block is the divided main system clock */
|
||||
inclk = (uint64_t) (Chip_Clock_GetMainClockRate() / div);
|
||||
|
||||
divf = Chip_Clock_GetUSARTNFRGDivider();
|
||||
if (divf == 0xFF) {
|
||||
/* Fractional part is enabled, get multiplier */
|
||||
mult = (uint32_t) Chip_Clock_GetUSARTNFRGMultiplier();
|
||||
|
||||
/* Get fractional error */
|
||||
inclk = (inclk * 256) / (uint64_t) (256 + mult);
|
||||
}
|
||||
}
|
||||
|
||||
return (uint32_t) inclk;
|
||||
}
|
||||
|
||||
/* Set USART 1/2/3/4 UART base rate */
|
||||
uint32_t Chip_Clock_SetUSARTNBaseClockRate(uint32_t rate, bool fEnable)
|
||||
{
|
||||
uint32_t div, inclk;
|
||||
|
||||
/* Input clock into FRG block is the main system clock */
|
||||
inclk = Chip_Clock_GetMainClockRate();
|
||||
|
||||
/* Get integer divider for coarse rate */
|
||||
div = inclk / rate;
|
||||
if (div == 0) {
|
||||
div = 1;
|
||||
}
|
||||
|
||||
/* Approximated rate with only integer divider */
|
||||
Chip_Clock_SetUSARTNBaseClockDiv((uint8_t) div);
|
||||
|
||||
if (fEnable) {
|
||||
uint32_t uart_fra_multiplier;
|
||||
|
||||
/* Reset FRG */
|
||||
Chip_SYSCTL_PeriphReset(RESET_FRG);
|
||||
|
||||
/* Enable fractional divider */
|
||||
Chip_Clock_SetUSARTNFRGDivider(0xFF);
|
||||
|
||||
/* Compute the fractional divisor (the lower byte is the
|
||||
fractional portion) */
|
||||
uart_fra_multiplier = ((inclk / div) * 256) / rate;
|
||||
|
||||
/* ...just the fractional portion (the lower byte) */
|
||||
Chip_Clock_SetUSARTNFRGMultiplier((uint8_t) uart_fra_multiplier);
|
||||
}
|
||||
else {
|
||||
/* Disable fractional generator and use integer divider only */
|
||||
Chip_Clock_SetUSARTNFRGDivider(0);
|
||||
}
|
||||
|
||||
return Chip_Clock_GetUSARTNBaseClockRate();
|
||||
}
|
||||
|
||||
/* Set System PLL clock source */
|
||||
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
|
||||
{
|
||||
LPC_SYSCTL->SYSPLLCLKSEL = (uint32_t) src;
|
||||
LPC_SYSCTL->SYSPLLCLKUEN = 0;
|
||||
LPC_SYSCTL->SYSPLLCLKUEN = 1;
|
||||
}
|
||||
|
||||
/* 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_USBPLLCLKSRC_T src)
|
||||
{
|
||||
LPC_SYSCTL->USBPLLCLKSEL = (uint32_t) src;
|
||||
LPC_SYSCTL->USBPLLCLKUEN = 0;
|
||||
LPC_SYSCTL->USBPLLCLKUEN = 1;
|
||||
}
|
||||
|
||||
/* Set main system clock source */
|
||||
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src)
|
||||
{
|
||||
LPC_SYSCTL->MAINCLKSEL = (uint32_t) src;
|
||||
LPC_SYSCTL->MAINCLKUEN = 0;
|
||||
LPC_SYSCTL->MAINCLKUEN = 1;
|
||||
}
|
||||
|
||||
/* Set USB clock source and divider */
|
||||
void Chip_Clock_SetUSBClockSource(CHIP_SYSCTL_USBCLKSRC_T src, uint32_t div)
|
||||
{
|
||||
LPC_SYSCTL->USBCLKSEL = (uint32_t) src;
|
||||
LPC_SYSCTL->USBCLKUEN = 0;
|
||||
LPC_SYSCTL->USBCLKUEN = 1;
|
||||
LPC_SYSCTL->USBCLKDIV = div;
|
||||
}
|
||||
|
||||
/* Set CLKOUT clock source and divider */
|
||||
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div)
|
||||
{
|
||||
LPC_SYSCTL->CLKOUTSEL = (uint32_t) src;
|
||||
LPC_SYSCTL->CLKOUTUEN = 0;
|
||||
LPC_SYSCTL->CLKOUTUEN = 1;
|
||||
LPC_SYSCTL->CLKOUTDIV = div;
|
||||
}
|
||||
|
||||
/* Return estimated watchdog oscillator rate */
|
||||
uint32_t Chip_Clock_GetWDTOSCRate(void)
|
||||
{
|
||||
return Chip_Clock_GetWDTRate(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_MAINOSC:
|
||||
clkRate = Chip_Clock_GetMainOscRate();
|
||||
break;
|
||||
|
||||
case SYSCTL_PLLCLKSRC_RTC32K:
|
||||
clkRate = Chip_Clock_GetRTCOscRate();
|
||||
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_USBPLLCLKSRC_T) (LPC_SYSCTL->USBPLLCLKSEL & 0x3)) {
|
||||
case SYSCTL_PLLCLKSRC_IRC:
|
||||
clkRate = Chip_Clock_GetIntOscRate();
|
||||
break;
|
||||
|
||||
case SYSCTL_PLLCLKSRC_MAINOSC:
|
||||
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;
|
||||
}
|
||||
117
hw/mcu/nxp/lpc_chip_11u6x/src/crc_11u6x.c
Normal file
117
hw/mcu/nxp/lpc_chip_11u6x/src/crc_11u6x.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* @brief LPC11u6x Cyclic Redundancy Check (CRC) Engine 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 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"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize CRC engine */
|
||||
void Chip_CRC_Init(void)
|
||||
{
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CRC);
|
||||
}
|
||||
|
||||
/* De-initialize CRC engine */
|
||||
void Chip_CRC_Deinit(void)
|
||||
{
|
||||
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_CRC);
|
||||
}
|
||||
|
||||
/* Sets up the CRC engine with defaults based on the polynomial to be used */
|
||||
void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly)
|
||||
{
|
||||
switch (poly) {
|
||||
case CRC_POLY_CRC16:
|
||||
Chip_CRC_UseCRC16();
|
||||
break;
|
||||
|
||||
case CRC_POLY_CRC32:
|
||||
Chip_CRC_UseCRC32();
|
||||
break;
|
||||
|
||||
case CRC_POLY_CCITT:
|
||||
default:
|
||||
Chip_CRC_UseCCITT();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure CRC engine and compute CCITT checksum from 8-bit data */
|
||||
uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes)
|
||||
{
|
||||
Chip_CRC_UseCCITT();
|
||||
while (bytes > 0) {
|
||||
Chip_CRC_Write8(*data);
|
||||
data++;
|
||||
bytes--;
|
||||
}
|
||||
|
||||
return Chip_CRC_Sum();
|
||||
}
|
||||
|
||||
/* Convenience function for computing a standard CRC16 checksum from 16-bit data block */
|
||||
uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords)
|
||||
{
|
||||
Chip_CRC_UseCRC16();
|
||||
while (hwords > 0) {
|
||||
Chip_CRC_Write16(*data);
|
||||
data++;
|
||||
hwords--;
|
||||
}
|
||||
|
||||
return Chip_CRC_Sum();
|
||||
}
|
||||
|
||||
/* Convenience function for computing a standard CRC32 checksum from 32-bit data block */
|
||||
uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words)
|
||||
{
|
||||
Chip_CRC_UseCRC32();
|
||||
while (words > 0) {
|
||||
Chip_CRC_Write32(*data);
|
||||
data++;
|
||||
words--;
|
||||
}
|
||||
|
||||
return Chip_CRC_Sum();
|
||||
}
|
||||
115
hw/mcu/nxp/lpc_chip_11u6x/src/dma_11u6x.c
Normal file
115
hw/mcu/nxp/lpc_chip_11u6x/src/dma_11u6x.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* @brief LPC11u6x DMA 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
|
||||
****************************************************************************/
|
||||
|
||||
/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase()
|
||||
function if a DMA SRAM table is needed. This table is correctly aligned for
|
||||
the DMA controller. */
|
||||
#if defined(__CC_ARM)
|
||||
/* Keil alignement to 256 bytes */
|
||||
__align(256) DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL];
|
||||
#endif /* defined (__CC_ARM) */
|
||||
|
||||
/* IAR support */
|
||||
#if defined(__ICCARM__)
|
||||
/* IAR EWARM alignement to 256 bytes */
|
||||
#pragma data_alignment=256
|
||||
DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL];
|
||||
#endif /* defined (__ICCARM__) */
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
/* GNU alignement to 256 bytes */
|
||||
DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL] __attribute__ ((aligned(256)));
|
||||
#endif /* defined (__GNUC__) */
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Set DMA transfer register interrupt bits (safe) */
|
||||
void Chip_DMA_SetTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pDMA->DMACH[ch].XFERCFG & ~0xFC000CC0;
|
||||
|
||||
pDMA->DMACH[ch].XFERCFG = temp | mask;
|
||||
}
|
||||
|
||||
/* Clear DMA transfer register interrupt bits (safe) */
|
||||
void Chip_DMA_ClearTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
/* Read and write values may not be the same, write 0 to
|
||||
undefined bits */
|
||||
temp = pDMA->DMACH[ch].XFERCFG & ~0xFC000CC0;
|
||||
|
||||
pDMA->DMACH[ch].XFERCFG = temp & ~mask;
|
||||
}
|
||||
|
||||
/* Update the transfer size in an existing DMA channel transfer configuration */
|
||||
void Chip_DMA_SetupChannelTransferSize(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t trans)
|
||||
{
|
||||
Chip_DMA_ClearTranBits(pDMA, ch, (0x3FF << 16));
|
||||
Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_XFERCOUNT(trans));
|
||||
}
|
||||
|
||||
/* Sets up a DMA channel with the passed DMA transfer descriptor */
|
||||
bool Chip_DMA_SetupTranChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch, DMA_CHDESC_T *desc)
|
||||
{
|
||||
bool good = false;
|
||||
DMA_CHDESC_T *pDesc = (DMA_CHDESC_T *) pDMA->SRAMBASE;
|
||||
|
||||
if ((Chip_DMA_GetActiveChannels(pDMA) & (1 << ch)) == 0) {
|
||||
/* Channel is not active, so update the descriptor */
|
||||
pDesc[ch] = *desc;
|
||||
|
||||
good = true;
|
||||
}
|
||||
|
||||
return good;
|
||||
}
|
||||
79
hw/mcu/nxp/lpc_chip_11u6x/src/eeprom.c
Normal file
79
hw/mcu/nxp/lpc_chip_11u6x/src/eeprom.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* @brief Common EEPROM support 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"
|
||||
#include "eeprom.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Write data to EEPROM */
|
||||
uint8_t Chip_EEPROM_Write(uint32_t dstAdd, uint8_t *ptr, uint32_t byteswrt)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_EEPROM_WRITE;
|
||||
command[1] = dstAdd;
|
||||
command[2] = (uint32_t) ptr;
|
||||
command[3] = byteswrt;
|
||||
command[4] = SystemCoreClock / 1000;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Read data from EEPROM */
|
||||
uint8_t Chip_EEPROM_Read(uint32_t srcAdd, uint8_t *ptr, uint32_t bytesrd)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_EEPROM_READ;
|
||||
command[1] = srcAdd;
|
||||
command[2] = (uint32_t) ptr;
|
||||
command[3] = bytesrd;
|
||||
command[4] = SystemCoreClock / 1000;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
104
hw/mcu/nxp/lpc_chip_11u6x/src/gpio_11u6x.c
Normal file
104
hw/mcu/nxp/lpc_chip_11u6x/src/gpio_11u6x.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* @brief LPC11u6x GPIO 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
|
||||
****************************************************************************/
|
||||
|
||||
/* 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, uint32_t pinMask, bool outSet)
|
||||
{
|
||||
if (outSet) {
|
||||
Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask);
|
||||
}
|
||||
else {
|
||||
Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask);
|
||||
}
|
||||
}
|
||||
48
hw/mcu/nxp/lpc_chip_11u6x/src/gpiogroup_11u6x.c
Normal file
48
hw/mcu/nxp/lpc_chip_11u6x/src/gpiogroup_11u6x.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* @brief LPC11U6x 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"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
554
hw/mcu/nxp/lpc_chip_11u6x/src/i2c_11u6x.c
Normal file
554
hw/mcu/nxp/lpc_chip_11u6x/src/i2c_11u6x.c
Normal file
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* @brief LPC11u6x I2C 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)
|
||||
#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_I2C0, SYSCTL_CLOCK_I2C0, Chip_I2C_EventHandler, NULL, NULL, NULL, 0},
|
||||
{LPC_I2C1, SYSCTL_CLOCK_I2C1, 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_GetMainClockRate();
|
||||
}
|
||||
|
||||
/* 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 0x48: /* SLA+R sent NAK received */
|
||||
xfer->status = I2C_STATUS_SLAVENAK;
|
||||
cclr &= ~I2C_CON_STO;
|
||||
break;
|
||||
|
||||
case 0x30: /* DATA 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;
|
||||
}
|
||||
197
hw/mcu/nxp/lpc_chip_11u6x/src/i2cm_11u6x.c
Normal file
197
hw/mcu/nxp/lpc_chip_11u6x/src/i2cm_11u6x.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* @brief LPC11u6x 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)
|
||||
{
|
||||
CHIP_SYSCTL_CLOCK_T clk = SYSCTL_CLOCK_I2C0;
|
||||
CHIP_SYSCTL_PERIPH_RESET_T rst = RESET_I2C0;
|
||||
|
||||
if (pI2C == LPC_I2C1) {
|
||||
clk = SYSCTL_CLOCK_I2C1;
|
||||
rst = RESET_I2C1;
|
||||
}
|
||||
/* Enable I2C clock */
|
||||
Chip_Clock_EnablePeriphClock(clk);
|
||||
|
||||
/* Peripheral reset control to I2C */
|
||||
Chip_SYSCTL_PeriphReset(rst);
|
||||
}
|
||||
|
||||
/* De-initializes the I2C peripheral registers to their default reset values */
|
||||
void Chip_I2CM_DeInit(LPC_I2C_T *pI2C)
|
||||
{
|
||||
CHIP_SYSCTL_CLOCK_T clk = SYSCTL_CLOCK_I2C0;
|
||||
|
||||
if (pI2C == LPC_I2C1) {
|
||||
clk = SYSCTL_CLOCK_I2C1;
|
||||
}
|
||||
/* Disable I2C clock */
|
||||
Chip_Clock_DisablePeriphClock(clk);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
175
hw/mcu/nxp/lpc_chip_11u6x/src/iap.c
Normal file
175
hw/mcu/nxp/lpc_chip_11u6x/src/iap.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* @brief Common FLASH support 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
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Prepare sector for write operation */
|
||||
uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_PREWRRITE_CMD;
|
||||
command[1] = strSector;
|
||||
command[2] = endSector;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Copy RAM to flash */
|
||||
uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_WRISECTOR_CMD;
|
||||
command[1] = dstAdd;
|
||||
command[2] = (uint32_t) srcAdd;
|
||||
command[3] = byteswrt;
|
||||
command[4] = SystemCoreClock / 1000;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Erase sector */
|
||||
uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_ERSSECTOR_CMD;
|
||||
command[1] = strSector;
|
||||
command[2] = endSector;
|
||||
command[3] = SystemCoreClock / 1000;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Blank check sector */
|
||||
uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_BLANK_CHECK_SECTOR_CMD;
|
||||
command[1] = strSector;
|
||||
command[2] = endSector;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Read part identification number */
|
||||
uint32_t Chip_IAP_ReadPID()
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_REPID_CMD;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[1];
|
||||
}
|
||||
|
||||
/* Read boot code version number */
|
||||
uint8_t Chip_IAP_ReadBootCode()
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_READ_BOOT_CODE_CMD;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* IAP compare */
|
||||
uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_COMPARE_CMD;
|
||||
command[1] = dstAdd;
|
||||
command[2] = srcAdd;
|
||||
command[3] = bytescmp;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Reinvoke ISP */
|
||||
uint8_t Chip_IAP_ReinvokeISP()
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_REINVOKE_ISP_CMD;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/* Read the unique ID */
|
||||
uint32_t Chip_IAP_ReadUID()
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_READ_UID_CMD;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[1];
|
||||
}
|
||||
|
||||
/* Erase page */
|
||||
uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage)
|
||||
{
|
||||
uint32_t command[5], result[4];
|
||||
|
||||
command[0] = IAP_ERASE_PAGE_CMD;
|
||||
command[1] = strPage;
|
||||
command[2] = endPage;
|
||||
command[3] = SystemCoreClock / 1000;
|
||||
iap_entry(command, result);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
110
hw/mcu/nxp/lpc_chip_11u6x/src/iocon_11u6x.c
Normal file
110
hw/mcu/nxp/lpc_chip_11u6x/src/iocon_11u6x.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* @brief LPC11u6x IOCON driver
|
||||
*
|
||||
* @note
|
||||
* Copyright(C) NXP Semiconductors, 2013
|
||||
* 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
|
||||
****************************************************************************/
|
||||
|
||||
/* Sets I/O Control pin mux */
|
||||
void Chip_IOCON_PinMuxSet(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin, uint32_t modefunc)
|
||||
{
|
||||
switch (port) {
|
||||
case 0:
|
||||
pIOCON->PIO0[pin] = modefunc;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pIOCON->PIO1[pin] = modefunc;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (pin >= 2) {
|
||||
pIOCON->PIO2B[pin - 2] = modefunc;
|
||||
}
|
||||
else {
|
||||
pIOCON->PIO2A[pin] = modefunc;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Set all I/O Control pin muxing*/
|
||||
void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T* pinArray, uint32_t arrayLength)
|
||||
{
|
||||
uint32_t ix;
|
||||
|
||||
for (ix = 0; ix < arrayLength; ix++ ) {
|
||||
Chip_IOCON_PinMuxSet(pIOCON, pinArray[ix].port, pinArray[ix].pin, pinArray[ix].modefunc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return value of I/O Control pin mux */
|
||||
uint32_t Chip_IOCON_GetPinMux(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin)
|
||||
{
|
||||
uint32_t iocon_value = 0;
|
||||
switch (port) {
|
||||
case 0:
|
||||
iocon_value = pIOCON->PIO0[pin];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
iocon_value = pIOCON->PIO1[pin];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (pin >= 2) {
|
||||
iocon_value = pIOCON->PIO2B[pin - 2];
|
||||
}
|
||||
else {
|
||||
iocon_value = pIOCON->PIO2A[pin];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return iocon_value;
|
||||
}
|
||||
92
hw/mcu/nxp/lpc_chip_11u6x/src/mtb.c
Normal file
92
hw/mcu/nxp/lpc_chip_11u6x/src/mtb.c
Normal file
@@ -0,0 +1,92 @@
|
||||
//*****************************************************************************
|
||||
// +--+
|
||||
// | ++----+
|
||||
// +-++ |
|
||||
// | |
|
||||
// +-+--+ |
|
||||
// | +--+--+
|
||||
// +----+ Copyright (c) 2013 Code Red Technologies Ltd.
|
||||
//
|
||||
// mtb.c
|
||||
//
|
||||
// Optionally defines an array to be used as a buffer for Micro Trace
|
||||
// Buffer (MTB) instruction trace on Cortex-M0+ parts
|
||||
//
|
||||
// Version : 130502
|
||||
//
|
||||
// Software License Agreement
|
||||
//
|
||||
// The software is owned by Code Red Technologies and/or its suppliers, and is
|
||||
// protected under applicable copyright laws. All rights are reserved. Any
|
||||
// use in violation of the foregoing restrictions may subject the user to criminal
|
||||
// sanctions under applicable laws, as well as to civil liability for the breach
|
||||
// of the terms and conditions of this license.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
|
||||
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
|
||||
// CODE RED TECHNOLOGIES LTD.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
/*******************************************************************
|
||||
* Symbols controlling behavior of this code...
|
||||
*
|
||||
* __MTB_DISABLE
|
||||
* If this symbol is defined, then the buffer array for the MTB
|
||||
* will not be created.
|
||||
*
|
||||
* __MTB_BUFFER_SIZE
|
||||
* Symbol specifying the sizer of the buffer array for the MTB.
|
||||
* This must be a power of 2 in size, and fit into the available
|
||||
* RAM. The MTB buffer will also be aligned to its 'size'
|
||||
* boundary and be placed at the start of a RAM bank (which
|
||||
* should ensure minimal or zero padding due to alignment).
|
||||
*
|
||||
* __MTB_RAM_BANK
|
||||
* Allows MTB Buffer to be placed into specific RAM bank. When
|
||||
* this is not defined, the "default" (first if there are
|
||||
* several) RAM bank is used.
|
||||
*******************************************************************/
|
||||
|
||||
// Ignore with none Code Red tools
|
||||
#if defined (__CODE_RED)
|
||||
|
||||
// Allow MTB to be removed by setting a define (via command line)
|
||||
#if !defined (__MTB_DISABLE)
|
||||
|
||||
// Allow for MTB buffer size being set by define set via command line
|
||||
// Otherwise provide small default buffer
|
||||
#if !defined (__MTB_BUFFER_SIZE)
|
||||
#define __MTB_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
// Check that buffer size requested is >0 bytes in size
|
||||
#if (__MTB_BUFFER_SIZE > 0)
|
||||
// Pull in MTB related macros
|
||||
#include <cr_mtb_buffer.h>
|
||||
|
||||
// Check if MYTB buffer is to be placed in specific RAM bank
|
||||
#if defined(__MTB_RAM_BANK)
|
||||
// Place MTB buffer into explicit bank of RAM
|
||||
__CR_MTB_BUFFER_EXT(__MTB_BUFFER_SIZE,__MTB_RAM_BANK);
|
||||
#else
|
||||
// Place MTB buffer into 'default' bank of RAM
|
||||
__CR_MTB_BUFFER(__MTB_BUFFER_SIZE);
|
||||
|
||||
#endif // defined(__MTB_RAM_BANK)
|
||||
|
||||
#endif // (__MTB_BUFFER_SIZE > 0)
|
||||
|
||||
#endif // !defined (__MTB_DISABLE)
|
||||
|
||||
#endif // defined (__CODE_RED)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
77
hw/mcu/nxp/lpc_chip_11u6x/src/pinint_11u6x.c
Normal file
77
hw/mcu/nxp/lpc_chip_11u6x/src/pinint_11u6x.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* @brief LPC11u6x Pin Interrupt and Pattern Match 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 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"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Set source for pattern match engine */
|
||||
void Chip_PININT_SetPatternMatchSrc(LPC_PIN_INT_T *pPININT, uint8_t chan, Chip_PININT_BITSLICE_T slice)
|
||||
{
|
||||
uint32_t pmsrc_reg;
|
||||
|
||||
/* Source source for pattern matching */
|
||||
pmsrc_reg = pPININT->PMSRC & ~(PININT_SRC_BITSOURCE_MASK << (PININT_SRC_BITSOURCE_START + (slice * 3)));
|
||||
pPININT->PMSRC = pmsrc_reg | (chan << (PININT_SRC_BITSOURCE_START + (slice * 3)));
|
||||
}
|
||||
|
||||
/* Configure Pattern match engine */
|
||||
void Chip_PININT_SetPatternMatchConfig(LPC_PIN_INT_T *pPININT, Chip_PININT_BITSLICE_T slice,
|
||||
Chip_PININT_BITSLICE_CFG_T slice_cfg, bool end_point)
|
||||
{
|
||||
uint32_t pmcfg_reg;
|
||||
|
||||
/* Configure bit slice configuration */
|
||||
pmcfg_reg = pPININT->PMCFG & ~(PININT_SRC_BITCFG_MASK << (PININT_SRC_BITCFG_START + (slice * 3)));
|
||||
pPININT->PMCFG = pmcfg_reg | (slice_cfg << (PININT_SRC_BITCFG_START + (slice * 3)));
|
||||
|
||||
/* If end point is true, enable the bits */
|
||||
if (end_point == true) {
|
||||
/* By default slice 7 is final component */
|
||||
if (slice != PININTBITSLICE7) {
|
||||
pPININT->PMCFG |= (0x1 << slice);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
hw/mcu/nxp/lpc_chip_11u6x/src/pmu_11u6x.c
Normal file
105
hw/mcu/nxp/lpc_chip_11u6x/src/pmu_11u6x.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* @brief LPC11u6x 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;
|
||||
|
||||
/* Enter sleep mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/* Enter MCU Deep Sleep mode */
|
||||
void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU)
|
||||
{
|
||||
SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos);
|
||||
pPMU->PCON = PMU_PCON_PM_DEEPSLEEP;
|
||||
|
||||
/* Enter sleep mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/* Enter MCU Power down mode */
|
||||
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();
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
else if (SleepMode == PMU_MCU_POWER_DOWN) {
|
||||
Chip_PMU_PowerDownState(pPMU);
|
||||
}
|
||||
else if (SleepMode == PMU_MCU_DEEP_PWRDOWN) {
|
||||
Chip_PMU_DeepPowerDownState(pPMU);
|
||||
}
|
||||
else {
|
||||
/* PMU_MCU_SLEEP */
|
||||
Chip_PMU_SleepState(pPMU);
|
||||
}
|
||||
}
|
||||
167
hw/mcu/nxp/lpc_chip_11u6x/src/ring_buffer.c
Normal file
167
hw/mcu/nxp/lpc_chip_11u6x/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;
|
||||
}
|
||||
79
hw/mcu/nxp/lpc_chip_11u6x/src/romdiv_11u6x.c
Normal file
79
hw/mcu/nxp/lpc_chip_11u6x/src/romdiv_11u6x.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* @brief Routines to overload "/" and "%" operator in C using ROM based divider library
|
||||
*
|
||||
* @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
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined( __GNUC__ )
|
||||
|
||||
/* Redirector of signed 32 bit integer divider to ROM routine */
|
||||
int __aeabi_idiv(int numerator, int denominator)
|
||||
{
|
||||
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
|
||||
return pROMDiv->sidiv(numerator, denominator);
|
||||
}
|
||||
|
||||
/* Redirector of unsigned 32 bit integer divider to ROM routine */
|
||||
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
|
||||
{
|
||||
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
|
||||
return pROMDiv->uidiv(numerator, denominator);
|
||||
}
|
||||
|
||||
/* Redirector of signed 32 bit integer divider with reminder to ROM routine */
|
||||
__value_in_regs IDIV_RETURN_T __aeabi_idivmod(int numerator, int denominator)
|
||||
{
|
||||
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
|
||||
return pROMDiv->sidivmod(numerator, denominator);
|
||||
}
|
||||
|
||||
/* Redirector of unsigned 32 bit integer divider with reminder to ROM routine */
|
||||
__value_in_regs UIDIV_RETURN_T __aeabi_uidivmod(unsigned numerator, unsigned denominator)
|
||||
{
|
||||
ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase;
|
||||
return pROMDiv->uidivmod(numerator, denominator);
|
||||
}
|
||||
|
||||
#endif /* !defined( __GNUC__ ) */
|
||||
60
hw/mcu/nxp/lpc_chip_11u6x/src/rtc_11u6x.c
Normal file
60
hw/mcu/nxp/lpc_chip_11u6x/src/rtc_11u6x.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* @brief LPC11u6x RTC 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
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize the RTC peripheral */
|
||||
void Chip_RTC_Init(LPC_RTC_T *pRTC)
|
||||
{
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_RTC);
|
||||
}
|
||||
|
||||
/* De-initialize the RTC peripheral */
|
||||
void Chip_RTC_DeInit(LPC_RTC_T *pRTC)
|
||||
{
|
||||
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_RTC);
|
||||
}
|
||||
98
hw/mcu/nxp/lpc_chip_11u6x/src/sct_11u6x.c
Normal file
98
hw/mcu/nxp/lpc_chip_11u6x/src/sct_11u6x.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* @brief LPC11u6x State Configurable Timer 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
|
||||
****************************************************************************/
|
||||
|
||||
/* SCT clock shared count flag */
|
||||
static uint8_t sctUsedCount;
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize SCT */
|
||||
void Chip_SCT_Init(LPC_SCT_T *pSCT)
|
||||
{
|
||||
if (sctUsedCount == 0) {
|
||||
/* Does not handle unbalanced Init() and DeInit() calls */
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SCT0_1);
|
||||
}
|
||||
sctUsedCount++;
|
||||
|
||||
if (pSCT == LPC_SCT0) {
|
||||
Chip_SYSCTL_PeriphReset(RESET_SCT0);
|
||||
}
|
||||
else {
|
||||
Chip_SYSCTL_PeriphReset(RESET_SCT1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutdown SCT */
|
||||
void Chip_SCT_DeInit(LPC_SCT_T *pSCT)
|
||||
{
|
||||
sctUsedCount--;
|
||||
if (sctUsedCount == 0) {
|
||||
/* Does not handle unbalanced Init() and DeInit() calls */
|
||||
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SCT0_1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set/Clear SCT control register */
|
||||
void Chip_SCT_SetClrControl(LPC_SCT_T *pSCT, uint32_t value, FunctionalState ena)
|
||||
{
|
||||
if (ena == ENABLE) {
|
||||
Chip_SCT_SetControl(pSCT, value);
|
||||
}
|
||||
else {
|
||||
Chip_SCT_ClearControl(pSCT, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set Conflict resolution */
|
||||
void Chip_SCT_SetConflictResolution(LPC_SCT_T *pSCT, uint8_t outnum, uint8_t value)
|
||||
{
|
||||
uint32_t tem;
|
||||
|
||||
tem = pSCT->RES & (~(0x03 << (2 * outnum)));
|
||||
pSCT->RES = tem | (value << (2 * outnum));
|
||||
}
|
||||
493
hw/mcu/nxp/lpc_chip_11u6x/src/ssp_11u6x.c
Normal file
493
hw/mcu/nxp/lpc_chip_11u6x/src/ssp_11u6x.c
Normal file
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
* @brief LPC11u6x SSP Registers and control 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
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* 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)));
|
||||
xf_setup->tx_cnt += 2;
|
||||
}
|
||||
else {
|
||||
Chip_SSP_SendFrame(pSSP, 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
106
hw/mcu/nxp/lpc_chip_11u6x/src/stopwatch_11u6x.c
Normal file
106
hw/mcu/nxp/lpc_chip_11u6x/src/stopwatch_11u6x.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* @brief LPC11u6x 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 */
|
||||
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;
|
||||
}
|
||||
106
hw/mcu/nxp/lpc_chip_11u6x/src/syscon_11u6x.c
Normal file
106
hw/mcu/nxp/lpc_chip_11u6x/src/syscon_11u6x.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* @brief LPC11U6X System Control functions
|
||||
*
|
||||
* Copyright(C) NXP Semiconductors, 2013
|
||||
* 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 */
|
||||
#define PDSLEEPUSEMASK 0x00000037
|
||||
#define PDSLEEPMASKTMP (SYSCTL_DEEPSLP_BOD_PD | SYSCTL_DEEPSLP_WDTOSC_PD)
|
||||
#define PDSLEEPMASK ((PDSLEEPUSEMASK) &~(PDSLEEPMASKTMP))
|
||||
|
||||
/* PDWAKECFG register mask */
|
||||
#define PDWAKEUPUSEMASK 0x00000800
|
||||
#define PDWAKEUPMASKTMP 0x000025FF
|
||||
|
||||
/* PDRUNCFG register mask */
|
||||
#define PDRUNCFGUSEMASK 0x0000C800
|
||||
#define PDRUNCFGMASKTMP 0x000025FF
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Setup a pin source for the pin interrupts (0-7) */
|
||||
void Chip_SYSCTL_SetPinInterrupt(uint32_t intno, uint8_t port, uint8_t pin)
|
||||
{
|
||||
if (port == 0) {
|
||||
/* Pins P0.1 to P0.23 only */
|
||||
LPC_SYSCTL->PINTSEL[intno] = (uint32_t) pin;
|
||||
} else {
|
||||
/* P1.1 to P1.31 and P2.0 to P2.7 */
|
||||
LPC_SYSCTL->PINTSEL[intno] = (uint32_t) ((port - 1) * 32 + pin + 24);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
165
hw/mcu/nxp/lpc_chip_11u6x/src/sysinit_11u6x.c
Normal file
165
hw/mcu/nxp/lpc_chip_11u6x/src/sysinit_11u6x.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* @brief LPC11u6x 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
|
||||
****************************************************************************/
|
||||
|
||||
/* Enable this definition to use the ROM API for PLL setup */
|
||||
// #define USE_ROM_API
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Clock and PLL initialization based on the internal oscillator */
|
||||
void Chip_SetupIrcClocking(void)
|
||||
{
|
||||
#if defined(USE_ROM_API)
|
||||
uint32_t cmd[4], resp[2];
|
||||
#endif
|
||||
|
||||
/* Turn on the IRC by clearing the power down bit */
|
||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRC_PD);
|
||||
|
||||
/* Select the PLL input in the IRC */
|
||||
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);
|
||||
|
||||
/* Setup FLASH access */
|
||||
Chip_FMC_SetFLASHAccess(FLASHTIM_3CLK_CPU);
|
||||
|
||||
#if defined(USE_ROM_API)
|
||||
/* Use ROM API for setting up PLL */
|
||||
cmd[0] = Chip_Clock_GetIntOscRate() / 1000; /* in KHz */
|
||||
cmd[1] = 48000000 / 1000; /* 48MHz system clock rate */
|
||||
cmd[2] = CPU_FREQ_EQU;
|
||||
cmd[3] = 48000000 / 10000; /* Timeout */
|
||||
LPC_PWRD_API->set_pll(cmd, resp);
|
||||
|
||||
/* Dead loop on fail */
|
||||
while (resp[0] != PLL_CMD_SUCCESS) {}
|
||||
#else
|
||||
/* Power down PLL to change the PLL divider ratio */
|
||||
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
|
||||
|
||||
/* Configure the PLL M and P dividers */
|
||||
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 4 = 48MHz
|
||||
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
||||
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
||||
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
||||
Chip_Clock_SetupSystemPLL(3, 1);
|
||||
|
||||
/* Turn on the PLL by clearing the power down bit */
|
||||
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);
|
||||
|
||||
/* Set main clock source to the system PLL. This will drive 24MHz
|
||||
for the main clock and 24MHz for the system clock */
|
||||
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Clock and PLL initialization based on the external oscillator */
|
||||
void Chip_SetupXtalClocking(void)
|
||||
{
|
||||
volatile int i;
|
||||
#if defined(USE_ROM_API)
|
||||
uint32_t cmd[4], resp[2];
|
||||
#endif
|
||||
|
||||
/* Powerup main oscillator */
|
||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSOSC_PD);
|
||||
|
||||
/* Wait for at least 580uS for osc to stabilize */
|
||||
for (i = 0; i < 2500; i++) {}
|
||||
|
||||
/* Set system PLL input to main oscillator */
|
||||
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
|
||||
|
||||
/* Setup FLASH access to 3 clocks */
|
||||
Chip_FMC_SetFLASHAccess(FLASHTIM_3CLK_CPU);
|
||||
|
||||
#if defined(USE_ROM_API)
|
||||
/* Use ROM API for setting up PLL */
|
||||
cmd[0] = Chip_Clock_GetMainOscRate() / 1000; /* in KHz */
|
||||
cmd[1] = 48000000 / 1000; /* 48MHz system clock rate */
|
||||
cmd[2] = CPU_FREQ_EQU;
|
||||
cmd[3] = 48000000 / 10000; /* Timeout */
|
||||
LPC_PWRD_API->set_pll(cmd, resp);
|
||||
|
||||
/* Dead loop on fail */
|
||||
while (resp[0] != PLL_CMD_SUCCESS) {}
|
||||
#else
|
||||
/* Power down PLL to change the PLL divider ratio */
|
||||
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
|
||||
|
||||
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 4 = 48MHz
|
||||
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
||||
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
||||
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
||||
Chip_Clock_SetupSystemPLL(3, 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);
|
||||
|
||||
/* 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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set up and initialize hardware prior to call to main */
|
||||
void Chip_SystemInit(void)
|
||||
{
|
||||
/* Initial internal clocking */
|
||||
Chip_SetupIrcClocking();
|
||||
}
|
||||
115
hw/mcu/nxp/lpc_chip_11u6x/src/timer_11u6x.c
Normal file
115
hw/mcu/nxp/lpc_chip_11u6x/src/timer_11u6x.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* @brief LPC11u6x 16/32-bit Timer/PWM control 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
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* 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)));
|
||||
}
|
||||
283
hw/mcu/nxp/lpc_chip_11u6x/src/uart_0_11u6x.c
Normal file
283
hw/mcu/nxp/lpc_chip_11u6x/src/uart_0_11u6x.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* @brief LPC11u6x USART0 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
|
||||
****************************************************************************/
|
||||
|
||||
/* Initializes the pUART peripheral */
|
||||
void Chip_UART0_Init(LPC_USART0_T *pUART)
|
||||
{
|
||||
/* A USART 0 divider of 1 is used with this driver */
|
||||
Chip_Clock_SetUSART0ClockDiv(1);
|
||||
|
||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_UART0);
|
||||
|
||||
/* Enable FIFOs by default, reset them */
|
||||
Chip_UART0_SetupFIFOS(pUART, (UART0_FCR_FIFO_EN | UART0_FCR_RX_RS | UART0_FCR_TX_RS));
|
||||
|
||||
/* Disable fractional divider */
|
||||
pUART->FDR = 0x10;
|
||||
}
|
||||
|
||||
/* De-initializes the pUART peripheral */
|
||||
void Chip_UART0_DeInit(LPC_USART0_T *pUART)
|
||||
{
|
||||
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_UART0);
|
||||
}
|
||||
|
||||
/* Transmit a byte array through the UART peripheral (non-blocking) */
|
||||
int Chip_UART0_Send(LPC_USART0_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_UART0_ReadLineStatus(pUART) & UART0_LSR_THRE) != 0)) {
|
||||
Chip_UART0_SendByte(pUART, *p8);
|
||||
p8++;
|
||||
sent++;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/* Transmit a byte array through the UART peripheral (blocking) */
|
||||
int Chip_UART0_SendBlocking(LPC_USART0_T *pUART, const void *data, int numBytes)
|
||||
{
|
||||
int pass, sent = 0;
|
||||
uint8_t *p8 = (uint8_t *) data;
|
||||
|
||||
while (numBytes > 0) {
|
||||
pass = Chip_UART0_Send(pUART, p8, numBytes);
|
||||
numBytes -= pass;
|
||||
sent += pass;
|
||||
p8 += pass;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/* Read data through the UART peripheral (non-blocking) */
|
||||
int Chip_UART0_Read(LPC_USART0_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_UART0_ReadLineStatus(pUART) & UART0_LSR_RDR) != 0)) {
|
||||
*p8 = Chip_UART0_ReadByte(pUART);
|
||||
p8++;
|
||||
readBytes++;
|
||||
}
|
||||
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
/* Read data through the UART peripheral (blocking) */
|
||||
int Chip_UART0_ReadBlocking(LPC_USART0_T *pUART, void *data, int numBytes)
|
||||
{
|
||||
int pass, readBytes = 0;
|
||||
uint8_t *p8 = (uint8_t *) data;
|
||||
|
||||
while (numBytes > 0) {
|
||||
pass = Chip_UART0_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_UART0_SetBaud(LPC_USART0_T *pUART, uint32_t baudrate)
|
||||
{
|
||||
uint32_t div, divh, divl, clkin;
|
||||
|
||||
/* USART clock input divider of 1 */
|
||||
Chip_Clock_SetUSART0ClockDiv(1);
|
||||
|
||||
/* 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_UART0_EnableDivisorAccess(pUART);
|
||||
Chip_UART0_SetDivisorLatches(pUART, divl, divh);
|
||||
Chip_UART0_DisableDivisorAccess(pUART);
|
||||
|
||||
/* Fractional FDR already setup for 1 in UART init */
|
||||
|
||||
return clkin / (div * 16);
|
||||
}
|
||||
|
||||
/* UART receive-only interrupt handler for ring buffers */
|
||||
void Chip_UART0_RXIntHandlerRB(LPC_USART0_T *pUART, RINGBUFF_T *pRB)
|
||||
{
|
||||
/* New data will be ignored if data not popped in time */
|
||||
while (Chip_UART0_ReadLineStatus(pUART) & UART0_LSR_RDR) {
|
||||
uint8_t ch = Chip_UART0_ReadByte(pUART);
|
||||
RingBuffer_Insert(pRB, &ch);
|
||||
}
|
||||
}
|
||||
|
||||
/* UART transmit-only interrupt handler for ring buffers */
|
||||
void Chip_UART0_TXIntHandlerRB(LPC_USART0_T *pUART, RINGBUFF_T *pRB)
|
||||
{
|
||||
uint8_t ch;
|
||||
|
||||
/* Fill FIFO until full or until TX ring buffer is empty */
|
||||
while ((Chip_UART0_ReadLineStatus(pUART) & UART0_LSR_THRE) != 0 &&
|
||||
RingBuffer_Pop(pRB, &ch)) {
|
||||
Chip_UART0_SendByte(pUART, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate a transmit ring buffer and start UART transmit */
|
||||
uint32_t Chip_UART0_SendRB(LPC_USART0_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_UART0_IntDisable(pUART, UART0_IER_THREINT);
|
||||
|
||||
/* Move as much data as possible into transmit ring buffer */
|
||||
ret = RingBuffer_InsertMult(pRB, p8, bytes);
|
||||
Chip_UART0_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_UART0_IntEnable(pUART, UART0_IER_THREINT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Copy data from a receive ring buffer */
|
||||
int Chip_UART0_ReadRB(LPC_USART0_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_UART0_IRQRBHandler(LPC_USART0_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
|
||||
{
|
||||
/* Handle transmit interrupt if enabled */
|
||||
if (pUART->IER & UART0_IER_THREINT) {
|
||||
Chip_UART0_TXIntHandlerRB(pUART, pTXRB);
|
||||
|
||||
/* Disable transmit interrupt if the ring buffer is empty */
|
||||
if (RingBuffer_IsEmpty(pTXRB)) {
|
||||
Chip_UART0_IntDisable(pUART, UART0_IER_THREINT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle receive interrupt */
|
||||
Chip_UART0_RXIntHandlerRB(pUART, pRXRB);
|
||||
}
|
||||
|
||||
/* Determines and sets best dividers to get a target baud rate */
|
||||
uint32_t Chip_UART0_SetBaudFDR(LPC_USART0_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_UART0_EnableDivisorAccess(pUART);
|
||||
Chip_UART0_SetDivisorLatches(pUART, UART0_LOAD_DLL(dl), UART0_LOAD_DLM(dl));
|
||||
Chip_UART0_DisableDivisorAccess(pUART);
|
||||
|
||||
/* Set best fractional divider */
|
||||
pUART->FDR = (UART0_FDR_MULVAL(mval) | UART0_FDR_DIVADDVAL(dval));
|
||||
|
||||
/* Return actual baud rate */
|
||||
actualRate = uClk / (16 * dl + 16 * dl * dval / mval);
|
||||
return actualRate;
|
||||
}
|
||||
280
hw/mcu/nxp/lpc_chip_11u6x/src/uart_n_11u6x.c
Normal file
280
hw/mcu/nxp/lpc_chip_11u6x/src/uart_n_11u6x.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* @brief LPC11u6xx USART0 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 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"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/* Counts instances of UART3 and 4 init calls for shared clock handling */
|
||||
static uint8_t uart_3_4_cnt;
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Return UART clock ID from the UART register address */
|
||||
static CHIP_SYSCTL_CLOCK_T getUARTClockID(LPC_USARTN_T *pUART)
|
||||
{
|
||||
if (pUART == LPC_USART1) {
|
||||
return SYSCTL_CLOCK_USART1;
|
||||
}
|
||||
else if (pUART == LPC_USART2) {
|
||||
return SYSCTL_CLOCK_USART2;
|
||||
}
|
||||
|
||||
return SYSCTL_CLOCK_USART3_4;
|
||||
}
|
||||
|
||||
/* UART clock enable */
|
||||
static void Chip_UARTN_EnableClock(LPC_USARTN_T *pUART)
|
||||
{
|
||||
CHIP_SYSCTL_CLOCK_T clk = getUARTClockID(pUART);
|
||||
|
||||
/* Special handling for shared UART 3/4 clock */
|
||||
if (clk == SYSCTL_CLOCK_USART3_4) {
|
||||
/* Does not handle unbalanced Init() and DeInit() calls */
|
||||
uart_3_4_cnt++;
|
||||
}
|
||||
|
||||
Chip_Clock_EnablePeriphClock(clk);
|
||||
}
|
||||
|
||||
/* UART clock disable */
|
||||
static void Chip_UARTN_DisableClock(LPC_USARTN_T *pUART)
|
||||
{
|
||||
CHIP_SYSCTL_CLOCK_T clk = getUARTClockID(pUART);
|
||||
|
||||
/* Special handling for shared UART 3/4 clock */
|
||||
if (clk != SYSCTL_CLOCK_USART3_4) {
|
||||
Chip_Clock_DisablePeriphClock(clk);
|
||||
}
|
||||
else {
|
||||
/* Does not handle unbalanced Init() and DeInit() calls */
|
||||
uart_3_4_cnt--;
|
||||
if (uart_3_4_cnt == 0) {
|
||||
Chip_Clock_DisablePeriphClock(clk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize the UART peripheral */
|
||||
void Chip_UARTN_Init(LPC_USARTN_T *pUART)
|
||||
{
|
||||
CHIP_SYSCTL_PERIPH_RESET_T resetID;
|
||||
|
||||
/* Enable USART clock */
|
||||
Chip_UARTN_EnableClock(pUART);
|
||||
|
||||
/* Select UART reset */
|
||||
if (pUART == LPC_USART1) {
|
||||
resetID = RESET_USART1;
|
||||
}
|
||||
else if (pUART == LPC_USART2) {
|
||||
resetID = RESET_USART2;
|
||||
}
|
||||
else if (pUART == LPC_USART3) {
|
||||
resetID = RESET_USART3;
|
||||
}
|
||||
else {
|
||||
resetID = RESET_USART4;
|
||||
}
|
||||
|
||||
Chip_SYSCTL_PeriphReset(resetID);
|
||||
}
|
||||
|
||||
/* Initialize the UART peripheral */
|
||||
void Chip_UARTN_DeInit(LPC_USARTN_T *pUART)
|
||||
{
|
||||
/* Disable USART clock */
|
||||
Chip_UARTN_DisableClock(pUART);
|
||||
}
|
||||
|
||||
/* Transmit a byte array through the UART peripheral (non-blocking) */
|
||||
int Chip_UARTN_Send(LPC_USARTN_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_UARTN_GetStatus(pUART) & UARTN_STAT_TXRDY) != 0)) {
|
||||
Chip_UARTN_SendByte(pUART, *p8);
|
||||
p8++;
|
||||
sent++;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/* Transmit a byte array through the UART peripheral (blocking) */
|
||||
int Chip_UARTN_SendBlocking(LPC_USARTN_T *pUART, const void *data, int numBytes)
|
||||
{
|
||||
int pass, sent = 0;
|
||||
uint8_t *p8 = (uint8_t *) data;
|
||||
|
||||
while (numBytes > 0) {
|
||||
pass = Chip_UARTN_Send(pUART, p8, numBytes);
|
||||
numBytes -= pass;
|
||||
sent += pass;
|
||||
p8 += pass;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/* Read data through the UART peripheral (non-blocking) */
|
||||
int Chip_UARTN_Read(LPC_USARTN_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_UARTN_GetStatus(pUART) & UARTN_STAT_RXRDY) != 0)) {
|
||||
*p8 = Chip_UARTN_ReadByte(pUART);
|
||||
p8++;
|
||||
readBytes++;
|
||||
}
|
||||
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
/* Read data through the UART peripheral (blocking) */
|
||||
int Chip_UARTN_ReadBlocking(LPC_USARTN_T *pUART, void *data, int numBytes)
|
||||
{
|
||||
int pass, readBytes = 0;
|
||||
uint8_t *p8 = (uint8_t *) data;
|
||||
|
||||
while (readBytes < numBytes) {
|
||||
pass = Chip_UARTN_Read(pUART, p8, numBytes);
|
||||
numBytes -= pass;
|
||||
readBytes += pass;
|
||||
p8 += pass;
|
||||
}
|
||||
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
/* Set baud rate for UART */
|
||||
void Chip_UARTN_SetBaud(LPC_USARTN_T *pUART, uint32_t baudrate)
|
||||
{
|
||||
uint32_t baudRateGenerator;
|
||||
baudRateGenerator = Chip_Clock_GetUSARTNBaseClockRate() / (16 * baudrate);
|
||||
pUART->BRG = baudRateGenerator - 1; /* baud rate */
|
||||
}
|
||||
|
||||
/* Set baud rate for UART using RTC32K oscillator */
|
||||
void Chip_UARTN_SetBaudWithRTC32K(LPC_USARTN_T *pUART, uint32_t baudrate)
|
||||
{
|
||||
/* Simple integer divide. 9600 is maximum baud rate. */
|
||||
pUART->BRG = (9600 / baudrate) - 1;
|
||||
|
||||
pUART->CFG |= UARTN_MODE_32K;
|
||||
}
|
||||
|
||||
/* UART receive-only interrupt handler for ring buffers */
|
||||
void Chip_UARTN_RXIntHandlerRB(LPC_USARTN_T *pUART, RINGBUFF_T *pRB)
|
||||
{
|
||||
/* New data will be ignored if data not popped in time */
|
||||
while ((Chip_UARTN_GetStatus(pUART) & UARTN_STAT_RXRDY) != 0) {
|
||||
uint8_t ch = Chip_UARTN_ReadByte(pUART);
|
||||
RingBuffer_Insert(pRB, &ch);
|
||||
}
|
||||
}
|
||||
|
||||
/* UART transmit-only interrupt handler for ring buffers */
|
||||
void Chip_UARTN_TXIntHandlerRB(LPC_USARTN_T *pUART, RINGBUFF_T *pRB)
|
||||
{
|
||||
uint8_t ch;
|
||||
|
||||
/* Fill FIFO until full or until TX ring buffer is empty */
|
||||
while (((Chip_UARTN_GetStatus(pUART) & UARTN_STAT_TXRDY) != 0) &&
|
||||
RingBuffer_Pop(pRB, &ch)) {
|
||||
Chip_UARTN_SendByte(pUART, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate a transmit ring buffer and start UART transmit */
|
||||
uint32_t Chip_UARTN_SendRB(LPC_USARTN_T *pUART, RINGBUFF_T *pRB, const void *data, int count)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint8_t *p8 = (uint8_t *) data;
|
||||
|
||||
/* Don't let UART transmit ring buffer change in the UART IRQ handler */
|
||||
Chip_UARTN_IntDisable(pUART, UARTN_INTEN_TXRDY);
|
||||
|
||||
/* Move as much data as possible into transmit ring buffer */
|
||||
ret = RingBuffer_InsertMult(pRB, p8, count);
|
||||
Chip_UARTN_TXIntHandlerRB(pUART, pRB);
|
||||
|
||||
/* Add additional data to transmit ring buffer if possible */
|
||||
ret += RingBuffer_InsertMult(pRB, (p8 + ret), (count - ret));
|
||||
|
||||
/* Enable UART transmit interrupt */
|
||||
Chip_UARTN_IntEnable(pUART, UARTN_INTEN_TXRDY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Copy data from a receive ring buffer */
|
||||
int Chip_UARTN_ReadRB(LPC_USARTN_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_UARTN_IRQRBHandler(LPC_USARTN_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
|
||||
{
|
||||
/* Handle transmit interrupt if enabled */
|
||||
if ((Chip_UARTN_GetStatus(pUART) & UARTN_STAT_TXRDY) != 0) {
|
||||
Chip_UARTN_TXIntHandlerRB(pUART, pTXRB);
|
||||
|
||||
/* Disable transmit interrupt if the ring buffer is empty */
|
||||
if (RingBuffer_IsEmpty(pTXRB)) {
|
||||
Chip_UARTN_IntDisable(pUART, UARTN_INTEN_TXRDY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle receive interrupt */
|
||||
Chip_UARTN_RXIntHandlerRB(pUART, pRXRB);
|
||||
}
|
||||
78
hw/mcu/nxp/lpc_chip_11u6x/src/wwdt_11u6x.c
Normal file
78
hw/mcu/nxp/lpc_chip_11u6x/src/wwdt_11u6x.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* @brief LPC11u6x WWDT 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
|
||||
****************************************************************************/
|
||||
|
||||
/* 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;
|
||||
pWWDT->WARNINT = 0x3FF;
|
||||
pWWDT->WINDOW = 0xFFFFFF;
|
||||
}
|
||||
|
||||
/* 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