commit 0c23bf065d540bb156607892a5965778c803146a Author: Stefan `Sec` Zehl Date: Wed May 11 23:17:30 2011 +0200 Stripped down version of microbuilder.eu lpc1343codebase I hope I didn't break anything too hard. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..305157a --- /dev/null +++ b/Makefile @@ -0,0 +1,108 @@ +########################################################################## +# User configuration and firmware specific object files +########################################################################## + +# The target, flash and ram of the LPC1xxx microprocessor. +# Use for the target the value: LPC11xx, LPC13xx or LPC17xx +TARGET = LPC13xx +FLASH = 32K +SRAM = 8K + +# For USB HID support the LPC134x reserves 384 bytes from the sram, +# if you don't want to use the USB features, just use 0 here. +SRAM_USB = 384 + +VPATH = +OBJS = main.o + +########################################################################## +# Project-specific files +########################################################################## + +VPATH += +OBJS += +LIBS += core/libcore.a lcd/libfont.a + +########################################################################## +# GNU GCC compiler prefix and location +########################################################################## + +CROSS_COMPILE = arm-none-eabi- +AS = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +SIZE = $(CROSS_COMPILE)size +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +OUTFILE = firmware +LPCRC = tools/lpcrc + +########################################################################## +# GNU GCC compiler flags +########################################################################## +ROOT_PATH = . +INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/core + +########################################################################## +# Startup files +########################################################################## + +LD_PATH = lpc1xxx +LD_SCRIPT = $(LD_PATH)/linkscript.ld +LD_TEMP = $(LD_PATH)/memory.ld + +ifeq (LPC11xx,$(TARGET)) + CORTEX_TYPE=m0 +else + CORTEX_TYPE=m3 +endif + +CPU_TYPE = cortex-$(CORTEX_TYPE) +VPATH += lpc1xxx +OBJS += $(TARGET)_handlers.o LPC1xxx_startup.o + +########################################################################## +# Compiler settings, parameters and flags +########################################################################## + +CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin +LDFLAGS = -nostartfiles -mthumb -mcpu=$(CPU_TYPE) -Wl,--gc-sections +LDLIBS = -lm +LDLIBS += -Lcore -lcore +LDLIBS += -Llcd -lfont +OCFLAGS = --strip-unneeded + +all: firmware + +%.o : %.c + $(CC) $(CFLAGS) -o $@ $< + +core/libcore.a: core/projectconfig.h + cd core && $(MAKE) + +lcd/libfont.a: + cd lcd && $(MAKE) + +tools/lpcrc: + cd tools && $(MAKE) + +firmware: $(OBJS) $(SYS_OBJS) $(LIBS) $(LPCRC) + -@echo "MEMORY" > $(LD_TEMP) + -@echo "{" >> $(LD_TEMP) + -@echo " flash(rx): ORIGIN = 0x00000000, LENGTH = $(FLASH)" >> $(LD_TEMP) + -@echo " sram(rwx): ORIGIN = 0x10000000+$(SRAM_USB), LENGTH = $(SRAM)-$(SRAM_USB)" >> $(LD_TEMP) + -@echo "}" >> $(LD_TEMP) + -@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP) + $(LD) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS) + -@echo "" + $(SIZE) $(OUTFILE).elf + -@echo "" + $(OBJCOPY) $(OCFLAGS) -O binary $(OUTFILE).elf $(OUTFILE).bin + -@echo "" + $(LPCRC) $(OUTFILE).bin + +clean: + rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex + @cd core && $(MAKE) clean + @cd tools && $(MAKE) clean + @cd lcd && $(MAKE) clean diff --git a/core/Makefile b/core/Makefile new file mode 100644 index 0000000..e7003f9 --- /dev/null +++ b/core/Makefile @@ -0,0 +1,85 @@ +########################################################################## +# User configuration and firmware specific object files +########################################################################## + +# The target, flash and ram of the LPC1xxx microprocessor. +# Use for the target the value: LPC11xx, LPC13xx or LPC17xx +TARGET = LPC13xx + +OBJS = sysinit.o +OBJS += adc/adc.o +#OBJS += cmd/cmd.o +OBJS += cpu/cpu.o +OBJS += gpio/gpio.o +OBJS += i2c/i2c.o +OBJS += iap/iap.o +OBJS += libc/ctype.o +OBJS += libc/stdio.o +OBJS += libc/string.o +OBJS += pmu/pmu.o +#OBJS += pwm/pwm.o +OBJS += ssp/ssp.o +OBJS += systick/systick.o +OBJS += timer16/timer16.o +OBJS += timer32/timer32.o +#OBJS += uart/uart.o +#OBJS += uart/uart_buf.o +#OBJS += usbcdc/cdcuser.o +#OBJS += usbcdc/cdc_buf.o +#OBJS += usbcdc/usbcore.o +#OBJS += usbcdc/usbdesc.o +#OBJS += usbcdc/usbhw.o +#OBJS += usbcdc/usbuser.o +#OBJS += usbhid-rom/usbconfig.o +#OBJS += usbhid-rom/usbhid.o +OBJS += wdt/wdt.o + +########################################################################## +# GNU GCC compiler prefix and location +########################################################################## + +CROSS_COMPILE = arm-none-eabi- +AS = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar +SIZE = $(CROSS_COMPILE)size +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +OUTFILE = firmware + +########################################################################## +# GNU GCC compiler flags +########################################################################## +ROOT_PATH = . +INCLUDE_PATHS = -I$(ROOT_PATH) -I.. + +########################################################################## +# Startup files +########################################################################## + +ifeq (LPC11xx,$(TARGET)) + CORTEX_TYPE=m0 +else + CORTEX_TYPE=m3 +endif + +CPU_TYPE = cortex-$(CORTEX_TYPE) + +########################################################################## +# Compiler settings, parameters and flags +########################################################################## + +CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin +LDFLAGS = -nostartfiles -mthumb -mcpu=$(CPU_TYPE) -Wl,--gc-sections + +all: libcore.a + +libcore.a: $(OBJS) + $(AR) rcs libcore.a $(OBJS) + +%.o : %.c projectconfig.h + $(CC) $(CFLAGS) -o $@ $< + +clean: + rm -f $(OBJS) libcore.a diff --git a/core/adc/adc.c b/core/adc/adc.c new file mode 100644 index 0000000..ada9dbb --- /dev/null +++ b/core/adc/adc.c @@ -0,0 +1,228 @@ +/**************************************************************************/ +/*! + @file adc.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section Description + + SW-based single-channel A/D conversion. If you wish to convert + multiple ADC channels simultaneously, this code will need to be + modified to work in BURST mode. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/adc/adc.h" + + void main (void) + { + cpuInit(); + adcInit(); + + uint32_t results = 0; + while(1) + { + // Get A/D conversion results from A/D channel 0 + results = adcRead(0); + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ +/**************************************************************************/ + +#include "adc.h" + +static bool _adcInitialised = false; +static uint8_t _adcLastChannel = 0; + +/**************************************************************************/ +/*! + @brief Returns the conversion results on the specified ADC channel. + + This function will manually start an A/D conversion on a single + channel and return the results. + + @param[in] channelNum + The A/D channel [0..7] that will be used during the A/D + conversion. (Note that only A/D channel's 0..3 are + configured by default in adcInit.) + + @return 0 if an overrun error occured, otherwise a 10-bit value + containing the A/D conversion results. + @warning Only AD channels 0..3 are configured for A/D in adcInit. + If you wish to use A/D pins 4..7 they will also need to + be added to the adcInit function. +*/ +/**************************************************************************/ +uint32_t adcRead (uint8_t channelNum) +{ + if (!_adcInitialised) adcInit(); + + uint32_t regVal, adcData; + + /* make sure that channel number is 0..7 */ + if ( channelNum >= 8 ) + { + // ToDo: Change this to throw an exception back + channelNum = 0; + } + + /* Deselect all channels */ + ADC_AD0CR &= ~ADC_AD0CR_SEL_MASK; + + /* Start converting now on the appropriate channel */ + ADC_AD0CR |= ADC_AD0CR_START_STARTNOW | (1 << channelNum); + + /* wait until end of A/D convert */ + while ( 1 ) + { + // Get data register results for the requested channel + switch (channelNum) + { + case 0: + regVal = (*(pREG32(ADC_AD0DR0))); + break; + case 1: + regVal = (*(pREG32(ADC_AD0DR1))); + break; + case 2: + regVal = (*(pREG32(ADC_AD0DR2))); + break; + case 3: + regVal = (*(pREG32(ADC_AD0DR3))); + break; + case 4: + regVal = (*(pREG32(ADC_AD0DR4))); + break; + case 5: + regVal = (*(pREG32(ADC_AD0DR5))); + break; + case 6: + regVal = (*(pREG32(ADC_AD0DR6))); + break; + case 7: + regVal = (*(pREG32(ADC_AD0DR7))); + break; + default: + regVal = (*(pREG32(ADC_AD0DR0))); + break; + } + + /* read result of A/D conversion */ + if (regVal & ADC_DR_DONE) + { + break; + } + } + + /* stop ADC */ + ADC_AD0CR &= ~ADC_AD0CR_START_MASK; + + /* return 0 if an overrun occurred */ + if ( regVal & ADC_DR_OVERRUN ) + { + return (1); + } + + /* return conversion results */ + adcData = (regVal >> 6) & 0x3FF; + return (adcData); +} + +/**************************************************************************/ +/*! + @brief Initialises the A/D converter and configures channels 0..3 + for 10-bit, SW-controlled A/D conversion. + + @return Nothing +*/ +/**************************************************************************/ +void adcInit (void) +{ + /* Disable Power down bit to the ADC block. */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_ADC); + + /* Enable AHB clock to the ADC. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_ADC); + + /* Digital pins need to have the 'analog' bit set in addition + to changing their pin function */ + + /* Set AD0 to analog input */ + IOCON_JTAG_TDI_PIO0_11 &= ~(IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK | + IOCON_JTAG_TDI_PIO0_11_FUNC_MASK | + IOCON_JTAG_TDI_PIO0_11_MODE_MASK); + IOCON_JTAG_TDI_PIO0_11 |= (IOCON_JTAG_TDI_PIO0_11_FUNC_AD0 & + IOCON_JTAG_TDI_PIO0_11_ADMODE_ANALOG); + + /* Set AD1 to analog input */ + IOCON_JTAG_TMS_PIO1_0 &= ~(IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK | + IOCON_JTAG_TMS_PIO1_0_FUNC_MASK | + IOCON_JTAG_TMS_PIO1_0_MODE_MASK); + IOCON_JTAG_TMS_PIO1_0 |= (IOCON_JTAG_TMS_PIO1_0_FUNC_AD1 & + IOCON_JTAG_TMS_PIO1_0_ADMODE_ANALOG); + + /* Set AD2 to analog input */ + IOCON_JTAG_TDO_PIO1_1 &= ~(IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK | + IOCON_JTAG_TDO_PIO1_1_FUNC_MASK | + IOCON_JTAG_TDO_PIO1_1_MODE_MASK); + IOCON_JTAG_TDO_PIO1_1 |= (IOCON_JTAG_TDO_PIO1_1_FUNC_AD2 & + IOCON_JTAG_TDO_PIO1_1_ADMODE_ANALOG); + + /* Set AD3 to analog input */ + IOCON_JTAG_nTRST_PIO1_2 &= ~(IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK | + IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK | + IOCON_JTAG_nTRST_PIO1_2_MODE_MASK); + IOCON_JTAG_nTRST_PIO1_2 |= (IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3 & + IOCON_JTAG_nTRST_PIO1_2_ADMODE_ANALOG); + + /* Note that in SW mode only one channel can be selected at a time (AD0 in this case) + To select multiple channels, ADC_AD0CR_BURST_HWSCANMODE must be used */ + ADC_AD0CR = (ADC_AD0CR_SEL_AD0 | /* SEL=1,select channel 0 on ADC0 */ + (((CFG_CPU_CCLK / SCB_SYSAHBCLKDIV) / 1000000 - 1 ) << 8) | /* CLKDIV = Fpclk / 1000000 - 1 */ + ADC_AD0CR_BURST_SWMODE | /* BURST = 0, no BURST, software controlled */ + ADC_AD0CR_CLKS_10BITS | /* CLKS = 0, 11 clocks/10 bits */ + ADC_AD0CR_START_NOSTART | /* START = 0 A/D conversion stops */ + ADC_AD0CR_EDGE_RISING); /* EDGE = 0 (CAP/MAT signal falling, trigger A/D conversion) */ + + /* Set initialisation flag */ + _adcInitialised = true; + + /* Set last channel flag to 0 (initialised above) */ + _adcLastChannel = 0; + + return; +} diff --git a/core/adc/adc.h b/core/adc/adc.h new file mode 100644 index 0000000..e2588a9 --- /dev/null +++ b/core/adc/adc.h @@ -0,0 +1,47 @@ +/**************************************************************************/ +/*! + @file adc.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/**************************************************************************/ + +#ifndef _ADC_H_ +#define _ADC_H_ + +#include "projectconfig.h" + +uint32_t adcRead (uint8_t channelNum); +void adcInit (void); + +#endif diff --git a/core/cmd/cmd.c b/core/cmd/cmd.c new file mode 100644 index 0000000..d618713 --- /dev/null +++ b/core/cmd/cmd.c @@ -0,0 +1,296 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file cmd.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include +#include + +#include "cmd.h" +#include "project/cmd_tbl.h" + +#ifdef CFG_PRINTF_UART +#include "core/uart/uart.h" +#endif + +#ifdef CFG_PRINTF_USBCDC + #include "core/usbcdc/cdcuser.h" + static char usbcdcBuf [32]; +#endif + +#if CFG_INTERFACE_ENABLEIRQ == 1 + #include "core/gpio/gpio.h" +#endif + +static uint8_t msg[CFG_INTERFACE_MAXMSGSIZE]; +static uint8_t *msg_ptr; + +/**************************************************************************/ +/*! + @brief Polls the relevant incoming message queue to see if anything + is waiting to be processed. +*/ +/**************************************************************************/ +void cmdPoll() +{ + #if defined CFG_PRINTF_UART + while (uartRxBufferDataPending()) + { + uint8_t c = uartRxBufferRead(); + cmdRx(c); + } + #endif + + #if defined CFG_PRINTF_USBCDC + int numBytesToRead, numBytesRead, numAvailByte; + + CDC_OutBufAvailChar (&numAvailByte); + if (numAvailByte > 0) + { + numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte; + numBytesRead = CDC_RdOutBuf (&usbcdcBuf[0], &numBytesToRead); + int i; + for (i = 0; i < numBytesRead; i++) + { + cmdRx(usbcdcBuf[i]); + } + } + #endif +} + +/**************************************************************************/ +/*! + @brief Handles a single incoming character. If a new line is + detected, the entire command will be passed to the command + parser. If a text character is detected, it will be added to + the message buffer until a new line is detected (up to the + maximum queue size, CFG_INTERFACE_MAXMSGSIZE). + + @param[in] c + The character to parse. +*/ +/**************************************************************************/ +void cmdRx(uint8_t c) +{ + // read out the data in the buffer and echo it back to the host. + switch (c) + { + case '\r': + case '\n': + // terminate the msg and reset the msg ptr. then send + // it to the handler for processing. + *msg_ptr = '\0'; + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%s", CFG_PRINTF_NEWLINE); + #endif + cmdParse((char *)msg); + msg_ptr = msg; + break; + + case '\b': + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%c",c); + #endif + if (msg_ptr > msg) + { + msg_ptr--; + } + break; + + default: + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%c",c); + #endif + *msg_ptr++ = c; + break; + } +} + +/**************************************************************************/ +/*! + @brief Displays the command prompt. The text that appears is defined + in projectconfig.h. +*/ +/**************************************************************************/ +static void cmdMenu() +{ + #if CFG_INTERFACE_SILENTMODE == 0 + printf(CFG_PRINTF_NEWLINE); + printf(CFG_INTERFACE_PROMPT); + #endif +} + +/**************************************************************************/ +/*! + @brief Parse the command line. This function tokenizes the command + input, then searches for the command table entry associated + with the commmand. Once found, it will jump to the + corresponding function. + + @param[in] cmd + The entire command string to be parsed +*/ +/**************************************************************************/ +void cmdParse(char *cmd) +{ + size_t argc, i = 0; + char *argv[30]; + + argv[i] = strtok(cmd, " "); + do + { + argv[++i] = strtok(NULL, " "); + } while ((i < 30) && (argv[i] != NULL)); + + argc = i; + for (i=0; i < CMD_COUNT; i++) + { + if (!strcmp(argv[0], cmd_tbl[i].command)) + { + if ((argc == 2) && !strcmp (argv [1], "?")) + { + // Display parameter help menu on 'command ?' + printf ("%s%s%s", cmd_tbl[i].description, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + printf ("%s%s", cmd_tbl[i].parameters, CFG_PRINTF_NEWLINE); + } + else if ((argc - 1) < cmd_tbl[i].minArgs) + { + // Too few arguments supplied + printf ("Too few arguments (%d expected)%s", cmd_tbl[i].minArgs, CFG_PRINTF_NEWLINE); + printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + } + else if ((argc - 1) > cmd_tbl[i].maxArgs) + { + // Too many arguments supplied + printf ("Too many arguments (%d maximum)%s", cmd_tbl[i].maxArgs, CFG_PRINTF_NEWLINE); + printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + } + else + { + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set the IRQ pin high at start of a command + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1); + #endif + // Dispatch command to the appropriate function + cmd_tbl[i].func(argc - 1, &argv [1]); + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set the IRQ pin low to signal the end of a command + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0); + #endif + } + + // Refresh the command prompt + cmdMenu(); + return; + } + } + printf("Command not recognized: '%s'%s%s", cmd, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + #if CFG_INTERFACE_SILENTMODE == 0 + printf("Type '?' for a list of all available commands%s", CFG_PRINTF_NEWLINE); + #endif + + cmdMenu(); +} + +/**************************************************************************/ +/*! + @brief Initialises the command line using the appropriate interface +*/ +/**************************************************************************/ +void cmdInit() +{ + #if defined CFG_INTERFACE && defined CFG_INTERFACE_UART + // Check if UART is already initialised + uart_pcb_t *pcb = uartGetPCB(); + if (!pcb->initialised) + { + uartInit(CFG_UART_BAUDRATE); + } + #endif + + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set IRQ pin as output + gpioSetDir(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, gpioDirection_Output); + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1); + #endif + + // init the msg ptr + msg_ptr = msg; + + // Show the menu + cmdMenu(); + + // Set the IRQ pin low by default + #if CFG_INTERFACE_ENABLEIRQ != 0 + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0); + #endif +} + +/**************************************************************************/ +/*! + 'help' command handler +*/ +/**************************************************************************/ +void cmd_help(uint8_t argc, char **argv) +{ + size_t i; + + printf("Command Description%s", CFG_PRINTF_NEWLINE); + printf("------- -----------%s", CFG_PRINTF_NEWLINE); + + // Display full command list + for (i=0; i < CMD_COUNT; i++) + { + if (!cmd_tbl[i].hidden) + { + printf ("%-10s %s%s", cmd_tbl[i].command, cmd_tbl[i].description, CFG_PRINTF_NEWLINE); + } + } + + printf("%sCommand parameters can be seen by entering: ?%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); +} diff --git a/core/cmd/cmd.h b/core/cmd/cmd.h new file mode 100644 index 0000000..b16a1e3 --- /dev/null +++ b/core/cmd/cmd.h @@ -0,0 +1,60 @@ +/**************************************************************************/ +/*! + @file cmd.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __CMD_H__ +#define __CMD_H__ + +#include "projectconfig.h" + +typedef struct +{ + char *command; + uint8_t minArgs; + uint8_t maxArgs; + uint8_t hidden; + void (*func)(uint8_t argc, char **argv); + const char *description; + const char *parameters; +} cmd_t; + +void cmdPoll(); +void cmdRx(uint8_t c); +void cmdParse(char *cmd); +void cmdInit(); + +#endif \ No newline at end of file diff --git a/core/cpu/cpu.c b/core/cpu/cpu.c new file mode 100644 index 0000000..fc04f7c --- /dev/null +++ b/core/cpu/cpu.c @@ -0,0 +1,169 @@ +/**************************************************************************/ +/*! + @file cpu.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Initialises the CPU and any core clocks. By default, the core clock + is set to run at 72MHz. In order to reduce power consumption all pins + are set to GPIO and input by cpuInit. + + @section EXAMPLE + @code + #include "lpc134x.h" + #include "core/cpu/cpu.h" + + int main (void) + { + // Initialise the CPU and setup the PLL + cpuInit(); + + while(1) + { + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "cpu.h" +#include "core/gpio/gpio.h" + +/**************************************************************************/ +/*! + @brief Configures the main clock/PLL + + The speed at which the MCU operates is set here using the SCB_PLLCTRL + register, and the SCB_PLLCLKSEL register can be used to select which + oscillator to use to generate the system clocks (the internal 12MHz + oscillator or an external crystal). + + @param[in] multiplier + The PLL multiplier + +*/ +/**************************************************************************/ +void cpuPllSetup (cpuMultiplier_t multiplier) +{ + uint32_t i; + + // Power up system oscillator + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSOSC_MASK); + + // Setup the crystal input (bypass disabled, 1-20MHz crystal) + SCB_SYSOSCCTRL = (SCB_SYSOSCCTRL_BYPASS_DISABLED | SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ); + + for (i = 0; i < 200; i++) + { + __asm volatile ("NOP"); + } + + // Configure PLL + SCB_PLLCLKSEL = SCB_CLKSEL_SOURCE_MAINOSC; // Select external crystal as PLL clock source + SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source + SCB_PLLCLKUEN = SCB_PLLCLKUEN_DISABLE; // Toggle update register once + SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source again + + // Wait until the clock is updated + while (!(SCB_PLLCLKUEN & SCB_PLLCLKUEN_UPDATE)); + + // Set clock speed + switch (multiplier) + { + case CPU_MULTIPLIER_2: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_2 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_3: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_3 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_4: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_4 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_5: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_5 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_6: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_6 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_1: + default: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_1 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + } + + // Enable system PLL + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSPLL_MASK); + + // Wait for PLL to lock + while (!(SCB_PLLSTAT & SCB_PLLSTAT_LOCK)); + + // Setup main clock (use PLL output) + SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT; + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source + SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; + + // Wait until the clock is updated + while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE)); + + // Disable USB clock by default (enabled in USB code) + SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPAD_PD); // Power-down USB PHY + SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPLL_PD); // Power-down USB PLL + + // Set system AHB clock + SCB_SYSAHBCLKDIV = SCB_SYSAHBCLKDIV_DIV1; + + // Enabled IOCON clock for I/O related peripherals + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_IOCON; +} + +/**************************************************************************/ +/*! + @brief Initialises the CPU, setting up the PLL, etc. +*/ +/**************************************************************************/ +void cpuInit (void) +{ + gpioInit(); + + // Set all GPIO pins to input by default + GPIO_GPIO0DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO1DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO2DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO3DIR &= ~(GPIO_IO_ALL); + + // Setup PLL (etc.) + cpuPllSetup(CPU_MULTIPLIER_6); +} diff --git a/core/cpu/cpu.h b/core/cpu/cpu.h new file mode 100644 index 0000000..eb0876a --- /dev/null +++ b/core/cpu/cpu.h @@ -0,0 +1,76 @@ +/**************************************************************************/ +/*! + @file cpu.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include "projectconfig.h" + +// Macro to initialise, reset and enable the cycle counter. +// This can be used for rough timing and performance tests +// by resetting the cycle counter before a function, and +// then reading the value after with "int count = DWT_CYCCNT" +// +// CPU_RESET_CYCLECOUNTER; +// ... do something +// int count = DWT_CYCCNT; +// +#define CPU_RESET_CYCLECOUNTER do { SCB_DEMCR = SCB_DEMCR | 0x01000000; \ + DWT_CYCCNT = 0; \ + DWT_CTRL = DWT_CTRL | 1 ; } while(0) + +/**************************************************************************/ +/*! + @brief Indicates the value for the PLL multiplier +*/ +/**************************************************************************/ +typedef enum +{ + CPU_MULTIPLIER_1 = 0, + CPU_MULTIPLIER_2, + CPU_MULTIPLIER_3, + CPU_MULTIPLIER_4, + CPU_MULTIPLIER_5, + CPU_MULTIPLIER_6 +} +cpuMultiplier_t; + +void cpuPllSetup (cpuMultiplier_t multiplier); +void cpuInit (void); + +#endif \ No newline at end of file diff --git a/core/gpio/gpio.c b/core/gpio/gpio.c new file mode 100644 index 0000000..830c58d --- /dev/null +++ b/core/gpio/gpio.c @@ -0,0 +1,550 @@ +/**************************************************************************/ +/*! + @file gpio.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the general purpose digital IO. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "gpio.h" + +#ifdef CFG_CHIBI +#include "drivers/chibi/chb_drvr.h" +volatile uint32_t chibi_counter = 0; +#endif + +static bool _gpioInitialised = false; + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 0 (currently checks pin 0.1) +*/ +/**************************************************************************/ +void PIOINT0_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(0, 1); + if (regVal) + { + gpioIntClear(0, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 1 (currently checks pin 1.1) +*/ +/**************************************************************************/ +void PIOINT1_IRQHandler(void) +{ + uint32_t regVal; + +#ifdef CFG_CHIBI + // Check for interrupt on 1.8 + regVal = gpioIntStatus(1, 8); + if (regVal) + { + chibi_counter++; + chb_ISR_Handler(); + gpioIntClear(1, 8); + } +#else + regVal = gpioIntStatus(1, 1); + if ( regVal ) + { + gpioIntClear(1, 1); + } +#endif + + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 2 (currently checks pin 2.1) +*/ +/**************************************************************************/ +void PIOINT2_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(2, 1); + if ( regVal ) + { + gpioIntClear(2, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 3 (currently checks pin 3.1) +*/ +/**************************************************************************/ +void PIOINT3_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(3, 1); + if ( regVal ) + { + gpioIntClear(3, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief Initialises GPIO and enables the GPIO interrupt + handler for all GPIO ports. +*/ +/**************************************************************************/ +void gpioInit (void) +{ + /* Enable AHB clock to the GPIO domain. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_GPIO); + + /* Set up NVIC when I/O pins are configured as external interrupts. */ + NVIC_EnableIRQ(EINT0_IRQn); + NVIC_EnableIRQ(EINT1_IRQn); + NVIC_EnableIRQ(EINT2_IRQn); + NVIC_EnableIRQ(EINT3_IRQn); + + /* Set initialisation flag */ + _gpioInitialised = true; + + return; +} + +/**************************************************************************/ +/*! + @brief Sets the direction (input/output) for a specific port pin + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..11) + @param[in] dir + The pin direction (gpioDirection_Input or + gpioDirection_Output) +*/ +/**************************************************************************/ +void gpioSetDir (uint32_t portNum, uint32_t bitPos, gpioDirection_t dir) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiodir = &GPIO_GPIO0DIR; + switch (portNum) + { + case 0: + gpiodir = &GPIO_GPIO0DIR; + break; + case 1: + gpiodir = &GPIO_GPIO1DIR; + break; + case 2: + gpiodir = &GPIO_GPIO2DIR; + break; + case 3: + gpiodir = &GPIO_GPIO3DIR; + break; + } + + // Toggle dir + dir == gpioDirection_Output ? (*gpiodir |= (1 << bitPos)) : (*gpiodir &= ~(1 << bitPos)); +} + +/**************************************************************************/ +/*! + @brief Gets the value for a specific port pin + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + + @return The current value for the specified port pin (0..1) +*/ +/**************************************************************************/ +uint32_t gpioGetValue (uint32_t portNum, uint32_t bitPos) +{ + if (!_gpioInitialised) gpioInit(); + + uint32_t value = 0; + + switch (portNum) + { + case 0: + value = (GPIO_GPIO0DATA & (1 << bitPos)) ? 1 : 0; + break; + case 1: + value = (GPIO_GPIO1DATA & (1 << bitPos)) ? 1 : 0; + break; + case 2: + value = (GPIO_GPIO2DATA & (1 << bitPos)) ? 1 : 0; + break; + case 3: + value = (GPIO_GPIO3DATA & (1 << bitPos)) ? 1 : 0; + break; + default: + break; + } + + return value; +} + +/**************************************************************************/ +/*! + @brief Sets the value for a specific port pin (only relevant when a + pin is configured as output). + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + @param[in] bitValue + The value to set for the specified bit (0..1). 0 will set + the pin low and 1 will set the pin high. +*/ +/**************************************************************************/ +void gpioSetValue (uint32_t portNum, uint32_t bitPos, uint32_t bitVal) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiodata = &GPIO_GPIO0DATA; + switch (portNum) + { + case 0: + gpiodata = &GPIO_GPIO0DATA; + break; + case 1: + gpiodata = &GPIO_GPIO1DATA; + break; + case 2: + gpiodata = &GPIO_GPIO2DATA; + break; + case 3: + gpiodata = &GPIO_GPIO3DATA; + break; + } + + // Toggle value + bitVal == 1 ? (*gpiodata |= (1 << bitPos)) : (*gpiodata &= ~(1 << bitPos)); +} + +/**************************************************************************/ +/*! + @brief Sets the interrupt sense, event, etc. + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + @param[in] sense + Whether the interrupt should be configured as edge or level + sensitive. + @param[in] edge + Whether one edge or both trigger an interrupt. + @param[in] event + Whether the rising or the falling edge (high or low) + should be used to trigger the interrupt. + + @section Example + + @code + // Initialise gpio + gpioInit(); + // Set GPIO1.8 to input + gpioSetDir(1, 8, gpioDirection_Input); + // Disable the internal pullup/down resistor on P1.8 + gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_Inactive); + // Setup an interrupt on GPIO1.8 + gpioSetInterrupt(1, // Port + 8, // Pin + gpioInterruptSense_Edge, // Edge/Level Sensitive + gpioInterruptEdge_Single, // Single/Double Edge + gpioInterruptEvent_ActiveHigh); // Rising/Falling + // Enable the interrupt + gpioIntEnable(1, 8); + @endcode +*/ +/**************************************************************************/ +void gpioSetInterrupt (uint32_t portNum, uint32_t bitPos, gpioInterruptSense_t sense, gpioInterruptEdge_t edge, gpioInterruptEvent_t event) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiois = &GPIO_GPIO0IS; + REG32 *gpioibe = &GPIO_GPIO0IBE; + REG32 *gpioiev = &GPIO_GPIO0IEV; + switch (portNum) + { + case 0: + gpiois = &GPIO_GPIO0IS; + gpioibe = &GPIO_GPIO0IBE; + gpioiev = &GPIO_GPIO0IEV; + break; + case 1: + gpiois = &GPIO_GPIO1IS; + gpioibe = &GPIO_GPIO1IBE; + gpioiev = &GPIO_GPIO1IEV; + break; + case 2: + gpiois = &GPIO_GPIO2IS; + gpioibe = &GPIO_GPIO2IBE; + gpioiev = &GPIO_GPIO2IEV; + break; + case 3: + gpiois = &GPIO_GPIO3IS; + gpioibe = &GPIO_GPIO3IBE; + gpioiev = &GPIO_GPIO3IEV; + break; + } + + if (gpioInterruptSense_Edge) + { + *gpiois &= ~(0x1<= MAX_TIMEOUT); +} + +/***************************************************************************** +** Function name: I2CInit +** +** Descriptions: Initialize I2C controller +** +** parameters: I2c mode is either MASTER or SLAVE +** Returned value: true or false, return false if the I2C +** interrupt handler was not installed correctly +** +*****************************************************************************/ +uint32_t i2cInit( uint32_t I2cMode ) +{ + SCB_PRESETCTRL |= (0x1<<1); + + // Enable I2C clock + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_I2C); + + // Configure pin 0.4 for SCL + IOCON_PIO0_4 &= ~(IOCON_PIO0_4_FUNC_MASK | IOCON_PIO0_4_I2CMODE_MASK); + IOCON_PIO0_4 |= (IOCON_PIO0_4_FUNC_I2CSCL); + + // Configure pin 0.5 for SDA + IOCON_PIO0_5 &= ~(IOCON_PIO0_5_FUNC_MASK | IOCON_PIO0_5_I2CMODE_MASK); + IOCON_PIO0_5 |= IOCON_PIO0_5_FUNC_I2CSDA; + + // Clear flags + I2C_I2CCONCLR = I2C_I2CCONCLR_AAC | + I2C_I2CCONCLR_SIC | + I2C_I2CCONCLR_STAC | + I2C_I2CCONCLR_I2ENC; + + // See p.128 for appropriate values for SCLL and SCLH +#if I2C_FAST_MODE_PLUS + IOCON_PIO0_4 |= (IOCON_PIO0_4_I2CMODE_FASTPLUSI2C); + IOCON_PIO0_5 |= (IOCON_PIO0_5_I2CMODE_FASTPLUSI2C); + I2C_I2CSCLL = I2C_SCLL_HS_SCLL; + I2C_I2CSCLH = I2C_SCLH_HS_SCLH; +#else + I2C_I2CSCLL = I2SCLL_SCLL; + I2C_I2CSCLH = I2SCLH_SCLH; +#endif + + if ( I2cMode == I2CSLAVE ) + { + I2C_I2CADR0 = SLAVE_ADDR; + } + + /* Enable the I2C Interrupt */ + NVIC_EnableIRQ(I2C_IRQn); + I2C_I2CCONSET = I2C_I2CCONSET_I2EN; + + return( TRUE ); +} + +/***************************************************************************** +** Function name: I2CEngine +** +** Descriptions: The routine to complete a I2C transaction +** from start to stop. All the intermitten +** steps are handled in the interrupt handler. +** Before this routine is called, the read +** length, write length and I2C master buffer +** need to be filled. +** +** parameters: None +** Returned value: Any of the I2CSTATE_... values. See i2c.h +** +*****************************************************************************/ +uint32_t i2cEngine( void ) +{ + I2CMasterState = I2CSTATE_IDLE; + RdIndex = 0; + WrIndex = 0; + if ( I2CStart() != TRUE ) + { + I2CStop(); + return ( FALSE ); + } + + /* wait until the state is a terminal state */ + while (I2CMasterState < 0x100); + + return ( I2CMasterState ); +} + +/****************************************************************************** +** End Of File +******************************************************************************/ + diff --git a/core/i2c/i2c.h b/core/i2c/i2c.h new file mode 100644 index 0000000..b1c59c1 --- /dev/null +++ b/core/i2c/i2c.h @@ -0,0 +1,83 @@ +/***************************************************************************** + * i2c.h: Header file for NXP LPC11xx Family Microprocessors + * + * Copyright(C) 2006, NXP Semiconductor + * Parts of this code are (C) 2010, MyVoice CAD/CAM Services + * All rights reserved. + * + * History + * 2006.07.19 ver 1.00 Preliminary version, first Release + * 2010.07.19 ver 1.10 Rob Jansen - MyVoice CAD/CAM Services + * Updated to reflect new code + * +******************************************************************************/ +#ifndef __I2C_H +#define __I2C_H + +#include "projectconfig.h" + +/* + * These are states returned by the I2CEngine: + * + * IDLE - is never returned but only used internally + * PENDING - is never returned but only used internally in the I2C functions + * ACK - The transaction finished and the slave returned ACK (on all bytes) + * NACK - The transaction is aborted since the slave returned a NACK + * SLA_NACK - The transaction is aborted since the slave returned a NACK on the SLA + * this can be intentional (e.g. an 24LC08 EEPROM states it is busy) + * or the slave is not available/accessible at all. + * ARB_LOSS - Arbitration loss during any part of the transaction. + * This could only happen in a multi master system or could also + * identify a hardware problem in the system. + */ +#define I2CSTATE_IDLE 0x000 +#define I2CSTATE_PENDING 0x001 +#define I2CSTATE_ACK 0x101 +#define I2CSTATE_NACK 0x102 +#define I2CSTATE_SLA_NACK 0x103 +#define I2CSTATE_ARB_LOSS 0x104 + +#define FAST_MODE_PLUS 0 + +#define I2C_BUFSIZE 6 +#define MAX_TIMEOUT 0x00FFFFFF + +#define I2CMASTER 0x01 +#define I2CSLAVE 0x02 + +#define SLAVE_ADDR 0xA0 +#define READ_WRITE 0x01 + +#define RD_BIT 0x01 + +#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */ +#define I2CONSET_AA 0x00000004 +#define I2CONSET_SI 0x00000008 +#define I2CONSET_STO 0x00000010 +#define I2CONSET_STA 0x00000020 + +#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */ +#define I2CONCLR_SIC 0x00000008 +#define I2CONCLR_STAC 0x00000020 +#define I2CONCLR_I2ENC 0x00000040 + +#define I2DAT_I2C 0x00000000 /* I2C Data Reg */ +#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */ +#define I2SCLH_SCLH 120 /* I2C SCL Duty Cycle High Reg */ +#define I2SCLL_SCLL 120 /* I2C SCL Duty Cycle Low Reg */ +#define I2SCLH_HS_SCLH 0x00000020 /* Fast Plus I2C SCL Duty Cycle High Reg */ +#define I2SCLL_HS_SCLL 0x00000020 /* Fast Plus I2C SCL Duty Cycle Low Reg */ + + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +extern void I2C_IRQHandler( void ); +extern uint32_t i2cInit( uint32_t I2cMode ); +extern uint32_t i2cEngine( void ); + +#endif /* end __I2C_H */ +/**************************************************************************** +** End Of File +*****************************************************************************/ diff --git a/core/iap/iap.c b/core/iap/iap.c new file mode 100644 index 0000000..b6af786 --- /dev/null +++ b/core/iap/iap.c @@ -0,0 +1,57 @@ +/**************************************************************************/ +/*! + @file iap.c + Source: http://knowledgebase.nxp.com/showthread.php?t=1594 +*/ +/**************************************************************************/ +#include "iap.h" + +IAP_return_t iap_return; + +#define IAP_ADDRESS 0x1FFF1FF1 +uint32_t param_table[5]; + +/**************************************************************************/ +/*! + Sends the IAP command and stores the result +*/ +/**************************************************************************/ +void iap_entry(uint32_t param_tab[], uint32_t result_tab[]) +{ + void (*iap)(uint32_t[], uint32_t[]); + iap = (void (*)(uint32_t[], uint32_t[]))IAP_ADDRESS; + iap(param_tab,result_tab); +} + +/**************************************************************************/ +/*! + Returns the CPU's unique 128-bit serial number (4 words long) + + @section Example + + @code + #include "core/iap/iap.h" + + IAP_return_t iap_return; + iap_return = iapReadSerialNumber(); + + if (iap_return.ReturnCode == 0) + { + printf("Serial Number: %08X %08X %08X %08X %s", + iap_return.Result[0], + iap_return.Result[1], + iap_return.Result[2], + iap_return.Result[3], + CFG_PRINTF_NEWLINE); + } + @endcode +*/ +/**************************************************************************/ +IAP_return_t iapReadSerialNumber(void) +{ + // ToDo: Why does IAP sometime cause the application to halt when read??? + param_table[0] = IAP_CMD_READUID; + iap_entry(param_table,(uint32_t*)(&iap_return)); + return iap_return; +} + diff --git a/core/iap/iap.h b/core/iap/iap.h new file mode 100644 index 0000000..d78bd31 --- /dev/null +++ b/core/iap/iap.h @@ -0,0 +1,60 @@ +/**************************************************************************/ +/*! + @file iap.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _IAP_H_ +#define _IAP_H_ + +#include "projectconfig.h" + +#define IAP_CMD_PREPARESECTORFORWRITE (50) +#define IAP_CMD_COPYRAMTOFLASH (51) +#define CAP_CMD_ERASESECTORS (52) +#define IAP_CMD_BLANKCHECKSECTOR (53) +#define IAP_CMD_READPARTID (54) +#define IAP_CMD_READBOOTCODEVERSION (55) +#define IAP_CMD_COMPARE (56) +#define IAP_CMD_REINVOKEISP (57) +#define IAP_CMD_READUID (58) + +typedef struct +{ + unsigned int ReturnCode; + unsigned int Result[4]; +} IAP_return_t; + +IAP_return_t iapReadSerialNumber(void); + +#endif \ No newline at end of file diff --git a/core/libc/ctype.c b/core/libc/ctype.c new file mode 100644 index 0000000..086065e --- /dev/null +++ b/core/libc/ctype.c @@ -0,0 +1,104 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Uwe Hermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +int isalpha(int c) +{ + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} + +int isascii(int c) +{ + return (c >= 0 && c <= 127); +} + +int isblank(int c) +{ + return (c == ' ' || c == '\t'); +} + +int iscntrl(int c) +{ + return (c <= 31 || c == 127); +} + +int isdigit(int c) +{ + return (c >= '0' && c <= '9'); +} + +int isalnum(int c) +{ + return isalpha(c) || isdigit(c); +} + +int isgraph(int c) +{ + return (c >= 33 && c <= 126); +} + +int islower(int c) +{ + return (c >= 'a' && c <= 'z'); +} + +int isprint(int c) +{ + return (c >= 32 && c <= 126); +} + + +int isspace(int c) +{ + return (c == ' ' || (c >= '\t' || c <= '\r')); +} + +int isupper(int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +int tolower(int c) +{ + return (c >= 'A' && c <= 'Z') ? (c + 32) : c; +} + +int toupper(int c) +{ + return (c >= 'a' && c <= 'z') ? (c - 32) : c; +} + +int isxdigit(int c) +{ + return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'z'); +} + +int ispunct(int c) +{ + return isprint(c) && !isspace(c) && !isalnum(c); +} diff --git a/core/libc/stdio.c b/core/libc/stdio.c new file mode 100755 index 0000000..bd1585b --- /dev/null +++ b/core/libc/stdio.c @@ -0,0 +1,475 @@ +/* + * Software License Agreement (BSD License) + * + * Based on original stdio.c released by Atmel + * Copyright (c) 2008, Atmel Corporation + * All rights reserved. + * + * Modified by Roel Verdult, Copyright (c) 2010 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include + +//------------------------------------------------------------------------------ +// Local Definitions +//------------------------------------------------------------------------------ + +// Maximum string size allowed (in bytes). +#define MAX_STRING_SIZE 255 + +//------------------------------------------------------------------------------ +// Global Variables +//------------------------------------------------------------------------------ + +// Required for proper compilation. +//struct _reent r = {0, (FILE*) 0, (FILE*) 1, (FILE*) 0}; +//struct _reent *_impure_ptr = &r; + +//------------------------------------------------------------------------------ +// Local Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Writes a character inside the given string. Returns 1. +// \param pStr Storage string. +// \param c Character to write. +//------------------------------------------------------------------------------ +signed int append_char(char *pStr, char c) +{ + *pStr = c; + return 1; +} + +//------------------------------------------------------------------------------ +// Writes a string inside the given string. +// Returns the size of the written +// string. +// \param pStr Storage string. +// \param pSource Source string. +//------------------------------------------------------------------------------ +signed int PutString(char *pStr, char fill, signed int width, const char *pSource) +{ + signed int num = 0; + + while (*pSource != 0) { + + *pStr++ = *pSource++; + num++; + } + + width -= num; + while (width > 0) { + + *pStr++ = fill; + num++; + width--; + } + + return num; +} + +//------------------------------------------------------------------------------ +// Writes an unsigned int inside the given string, using the provided fill & +// width parameters. +// Returns the size in characters of the written integer. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param value Integer value. +//------------------------------------------------------------------------------ +signed int PutUnsignedInt( + char *pStr, + char fill, + signed int width, + unsigned int value) +{ + signed int num = 0; + + // Take current digit into account when calculating width + width--; + + // Recursively write upper digits + if ((value / 10) > 0) { + + num = PutUnsignedInt(pStr, fill, width, value / 10); + pStr += num; + } + // Write filler characters + else { + + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + } + + // Write lower digit + num += append_char(pStr, (value % 10) + '0'); + + return num; +} + +//------------------------------------------------------------------------------ +// Writes a signed int inside the given string, using the provided fill & width +// parameters. +// Returns the size of the written integer. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param value Signed integer value. +//------------------------------------------------------------------------------ +signed int PutSignedInt( + char *pStr, + char fill, + signed int width, + signed int value) +{ + signed int num = 0; + unsigned int absolute; + + // Compute absolute value + if (value < 0) { + + absolute = -value; + } + else { + + absolute = value; + } + + // Take current digit into account when calculating width + width--; + + // Recursively write upper digits + if ((absolute / 10) > 0) { + + if (value < 0) { + + num = PutSignedInt(pStr, fill, width, -(absolute / 10)); + } + else { + + num = PutSignedInt(pStr, fill, width, absolute / 10); + } + pStr += num; + } + else { + + // Reserve space for sign + if (value < 0) { + + width--; + } + + // Write filler characters + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + + // Write sign + if (value < 0) { + + num += append_char(pStr, '-'); + pStr++; + } + } + + // Write lower digit + num += append_char(pStr, (absolute % 10) + '0'); + + return num; +} + +//------------------------------------------------------------------------------ +// Writes an hexadecimal value into a string, using the given fill, width & +// capital parameters. +// Returns the number of char written. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param maj Indicates if the letters must be printed in lower- or upper-case. +// \param value Hexadecimal value. +//------------------------------------------------------------------------------ +signed int PutHexa( + char *pStr, + char fill, + signed int width, + unsigned char maj, + unsigned int value) +{ + signed int num = 0; + + // Decrement width + width--; + + // Recursively output upper digits + if ((value >> 4) > 0) { + + num += PutHexa(pStr, fill, width, maj, value >> 4); + pStr += num; + } + // Write filler chars + else { + + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + } + + // Write current digit + if ((value & 0xF) < 10) { + + append_char(pStr, (value & 0xF) + '0'); + } + else if (maj) { + + append_char(pStr, (value & 0xF) - 10 + 'A'); + } + else { + + append_char(pStr, (value & 0xF) - 10 + 'a'); + } + num++; + + return num; +} + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pStr Destination string. +/// \param length Length of Destination string. +/// \param pFormat Format string. +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap) +{ + char fill; + unsigned char width; + signed int num = 0; + signed int size = 0; + + // Clear the string + if (pStr) { + + *pStr = 0; + } + + // Phase string + while (*pFormat != 0 && size < length) { + + // Normal character + if (*pFormat != '%') { + + *pStr++ = *pFormat++; + size++; + } + // Escaped '%' + else if (*(pFormat+1) == '%') { + + *pStr++ = '%'; + pFormat += 2; + size++; + } + // Token delimiter + else { + + fill = ' '; + width = 0; + pFormat++; + + // Parse filler + if (*pFormat == '0') { + + fill = '0'; + pFormat++; + } + + // Ignore justifier + if (*pFormat == '-') { + pFormat++; + } + + // Parse width + while ((*pFormat >= '0') && (*pFormat <= '9')) { + + width = (width*10) + *pFormat-'0'; + pFormat++; + } + + // Check if there is enough space + if (size + width > length) { + + width = length - size; + } + + // Parse type + switch (*pFormat) { + case 'd': + case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break; + case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break; + case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break; + case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break; + case 's': num = PutString(pStr, fill, width, va_arg(ap, char *)); break; + case 'c': num = append_char(pStr, va_arg(ap, unsigned int)); break; + default: + return EOF; + } + + pFormat++; + pStr += num; + size += num; + } + } + + // NULL-terminated (final \0 is not counted) + if (size < length) { + + *pStr = 0; + } + else { + + *(--pStr) = 0; + size--; + } + + return size; +} + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pString Destination string. +/// \param length Length of Destination string. +/// \param pFormat Format string. +/// \param ... Other arguments +//------------------------------------------------------------------------------ +signed int snprintf(char *pString, size_t length, const char *pFormat, ...) +{ + va_list ap; + signed int rc; + + va_start(ap, pFormat); + rc = vsnprintf(pString, length, pFormat, ap); + va_end(ap); + + return rc; +} + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pString Destination string. +/// \param pFormat Format string. +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vsprintf(char *pString, const char *pFormat, va_list ap) +{ + return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap); +} + +//------------------------------------------------------------------------------ +/// Outputs a formatted string on the DBGU stream. Format arguments are given +/// in a va_list instance. +/// \param pFormat Format string +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vprintf(const char *pFormat, va_list ap) +{ + char pStr[MAX_STRING_SIZE]; + char pError[] = "stdio.c: increase MAX_STRING_SIZE\r\n"; + + // Write formatted string in buffer + if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) { + + puts(pError); + while (1); // Increase MAX_STRING_SIZE + } + + // Display string + return puts(pStr); +} + +//------------------------------------------------------------------------------ +/// Outputs a formatted string on the DBGU stream, using a variable number of +/// arguments. +/// \param pFormat Format string. +//------------------------------------------------------------------------------ +signed int printf(const char *pFormat, ...) +{ + va_list ap; + signed int result; + + // Forward call to vprintf + va_start(ap, pFormat); + result = vprintf(pFormat, ap); + va_end(ap); + + return result; +} + + +//------------------------------------------------------------------------------ +/// Writes a formatted string inside another string. +/// \param pStr Storage string. +/// \param pFormat Format string. +//------------------------------------------------------------------------------ +signed int sprintf(char *pStr, const char *pFormat, ...) +{ + va_list ap; + signed int result; + + // Forward call to vsprintf + va_start(ap, pFormat); + result = vsprintf(pStr, pFormat, ap); + va_end(ap); + + return result; +} \ No newline at end of file diff --git a/core/libc/string.c b/core/libc/string.c new file mode 100755 index 0000000..544f2ac --- /dev/null +++ b/core/libc/string.c @@ -0,0 +1,328 @@ +/* + * Software License Agreement (BSD License) + * + * Based on original stdio.c released by Atmel + * Copyright (c) 2008, Atmel Corporation + * All rights reserved. + * + * Modified by Roel Verdult, Copyright (c) 2010 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Copies data from a source buffer into a destination buffer. The two buffers +/// must NOT overlap. Returns the destination buffer. +/// \param pDestination Destination buffer. +/// \param pSource Source buffer. +/// \param num Number of bytes to copy. +//------------------------------------------------------------------------------ +void * memcpy(void *pDestination, const void *pSource, size_t num) +{ + unsigned char *pByteDestination; + unsigned char *pByteSource; + unsigned int *pAlignedSource = (unsigned int *) pSource; + unsigned int *pAlignedDestination = (unsigned int *) pDestination; + + // If num is more than 4 bytes, and both dest. and source are aligned, + // then copy dwords + if ((((unsigned int) pAlignedDestination & 0x3) == 0) + && (((unsigned int) pAlignedSource & 0x3) == 0) + && (num >= 4)) { + + while (num >= 4) { + + *pAlignedDestination++ = *pAlignedSource++; + num -= 4; + } + } + + // Copy remaining bytes + pByteDestination = (unsigned char *) pAlignedDestination; + pByteSource = (unsigned char *) pAlignedSource; + while (num--) { + + *pByteDestination++ = *pByteSource++; + } + + return pDestination; +} + +//------------------------------------------------------------------------------ +/// Fills a memory region with the given value. Returns a pointer to the +/// memory region. +/// \param pBuffer Pointer to the start of the memory region to fill +/// \param value Value to fill the region with +/// \param num Size to fill in bytes +//------------------------------------------------------------------------------ +void * memset(void *pBuffer, int value, size_t num) +{ + unsigned char *pByteDestination; + unsigned int *pAlignedDestination = (unsigned int *) pBuffer; + unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value; + + // Set words if possible + if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) { + while (num >= 4) { + *pAlignedDestination++ = alignedValue; + num -= 4; + } + } + // Set remaining bytes + pByteDestination = (unsigned char *) pAlignedDestination; + while (num--) { + *pByteDestination++ = value; + } + return pBuffer; +} + +void* memmove(void *s1, const void *s2, size_t n) +{ + char *s=(char*)s2, *d=(char*)s1; + + if(d > s){ + s+=n-1; + d+=n-1; + while(n){ + *d--=*s--; + n--; + } + }else if(d < s) + while(n){ + *d++=*s++; + n--; + } + return s1; +} + +int memcmp(const void *av, const void *bv, size_t len) +{ + const unsigned char *a = av; + const unsigned char *b = bv; + size_t i; + + for (i=0; i0 if 1st string > 2nd string +/// Return <0 if 1st string < 2nd string +/// \param pString1 Pointer to the start of the 1st string. +/// \param pString2 Pointer to the start of the 2nd string. +/// \param count Number of bytes that should be compared. +//----------------------------------------------------------------------------- +int strncmp(const char *pString1, const char *pString2, size_t count) +{ + int r; + + while(count) { + r = *pString1 - *pString2; + if (r == 0) { + if (*pString1 == 0) { + break; + } + pString1++; + pString2++; + count--; + continue; + } + return r; + } + return 0; +} + +//----------------------------------------------------------------------------- +/// Copy the first number of bytes from source string to destination string +/// Return the pointer to the destination string. +/// \param pDestination Pointer to the start of destination string. +/// \param pSource Pointer to the start of the source string. +/// \param count Number of bytes that should be copied. +//----------------------------------------------------------------------------- +char * strncpy(char *pDestination, const char *pSource, size_t count) +{ + char *pSaveDest = pDestination; + + while (count) { + *pDestination = *pSource; + if (*pSource == 0) { + break; + } + pDestination++; + pSource++; + count--; + } + return pSaveDest; +} + +// Following code is based on the BSD licensed code released by UoC +// Copyright (c) 1988 Regents of the University of California + +int strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + return (*(unsigned char *)s1 - *(unsigned char *)--s2); +} + +char *strtok(char *s, const char *delim) +{ + static char *last; + return strtok_r(s, delim, &last); +} + +char *strtok_r(char *s, const char *delim, char **last) +{ + char *spanp; + int c, sc; + char *tok; + + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} diff --git a/core/lpc134x.h b/core/lpc134x.h new file mode 100644 index 0000000..d07811c --- /dev/null +++ b/core/lpc134x.h @@ -0,0 +1,3536 @@ +/**************************************************************************/ +/*! + @file lpc134x.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + LPC1343 header file, based on V0.10 of the LPC1343 User Manual. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _LPC134X_H_ +#define _LPC134X_H_ + +#include "sysdefs.h" +#include "projectconfig.h" + +/*############################################################################## +## System Control Block +##############################################################################*/ + +#define SCB_BASE_ADDRESS (*(pREG32 (0x40048000))) // System control block base address + +#define SCB_MEMREMAP (*(pREG32 (0x40048000))) // System memory remap +#define SCB_PRESETCTRL (*(pREG32 (0x40048004))) // Peripheral reset control +#define SCB_PLLCTRL (*(pREG32 (0x40048008))) // System PLL control +#define SCB_PLLSTAT (*(pREG32 (0x4004800C))) // System PLL status +#define SCB_USBPLLCTRL (*(pREG32 (0x40048010))) // USB PLL control +#define SCB_USBPLLSTAT (*(pREG32 (0x40048014))) // USB PLL status +#define SCB_SYSOSCCTRL (*(pREG32 (0x40048020))) // System oscillator control +#define SCB_WDTOSCCTRL (*(pREG32 (0x40048024))) // Watchdog oscillator control +#define SCB_IRCCTRL (*(pREG32 (0x40048028))) // IRC control +#define SCB_RESETSTAT (*(pREG32 (0x40048030))) // System reset status register +#define SCB_PLLCLKSEL (*(pREG32 (0x40048040))) // System PLL clock source select +#define SCB_PLLCLKUEN (*(pREG32 (0x40048044))) // System PLL clock source update enable +#define SCB_USBPLLCLKSEL (*(pREG32 (0x40048048))) // USB PLL clock source select +#define SCB_USBPLLCLKUEN (*(pREG32 (0x4004804C))) // USB PLL clock source update enable +#define SCB_MAINCLKSEL (*(pREG32 (0x40048070))) // Main clock source select +#define SCB_MAINCLKUEN (*(pREG32 (0x40048074))) // Main clock source update enable +#define SCB_SYSAHBCLKDIV (*(pREG32 (0x40048078))) // System AHB clock divider +#define SCB_SYSAHBCLKCTRL (*(pREG32 (0x40048080))) // System AHB clock control +#define SCB_SSP0CLKDIV (*(pREG32 (0x40048094))) // SSP0 clock divider +#define SCB_UARTCLKDIV (*(pREG32 (0x40048098))) // UART clock divider +#define SCB_SYSTICKCLKDIV (*(pREG32 (0x400480B0))) // System tick clock divider +#define SCB_USBCLKSEL (*(pREG32 (0x400480C0))) // USB clock source select +#define SCB_USBCLKUEN (*(pREG32 (0x400480C4))) // USB clock source update enable +#define SCB_USBCLKDIV (*(pREG32 (0x400480C8))) // USB clock divider +#define SCB_WDTCLKSEL (*(pREG32 (0x400480D0))) // Watchdog clock source select +#define SCB_WDTCLKUEN (*(pREG32 (0x400480D4))) // Watchdog clock source update enable +#define SCB_WDTCLKDIV (*(pREG32 (0x400480D8))) // Watchdog clock divider +#define SCB_CLKOUTCLKSEL (*(pREG32 (0x400480E0))) // CLKOUT clock source select +#define SCB_CLKOUTCLKUEN (*(pREG32 (0x400480E4))) // CLKOUT clock source update enable +#define SCB_CLKOUTCLKDIV (*(pREG32 (0x400480E8))) // CLKOUT clock divider +#define SCB_PIOPORCAP0 (*(pREG32 (0x40048100))) // POR captured PIO status 0 +#define SCB_PIOPORCAP1 (*(pREG32 (0x40048104))) // POR captured PIO status 1 +#define SCB_BODCTRL (*(pREG32 (0x40048150))) // Brown-out detector control +#define SCB_SYSTICKCCAL (*(pREG32 (0x40048158))) // System tick counter calibration +#define SCB_STARTAPRP0 (*(pREG32 (0x40048200))) // Start logic edge control register 0; bottom 32 interrupts +#define SCB_STARTERP0 (*(pREG32 (0x40048204))) // Start logic signal enable register 0; bottom 32 interrupts +#define SCB_STARTRSRP0CLR (*(pREG32 (0x40048208))) // Start logic reset register 0; bottom 32 interrupts +#define SCB_STARTSRP0 (*(pREG32 (0x4004820C))) // Start logic status register 0; bottom 32 interrupts +#define SCB_STARTAPRP1 (*(pREG32 (0x40048210))) // Start logic edge control register 1; top 8 interrupts +#define SCB_STARTERP1 (*(pREG32 (0x40048214))) // Start logic signal enable register 1; top 8 interrupts +#define SCB_STARTRSRP1CLR (*(pREG32 (0x40048218))) // Start logic reset register 1; top 8 interrupts +#define SCB_STARTSRP1 (*(pREG32 (0x4004821C))) // Start logic status register 1; top 8 interrupts +#define SCB_PDSLEEPCFG (*(pREG32 (0x40048230))) // Power-down states in Deep-sleep mode +#define SCB_PDAWAKECFG (*(pREG32 (0x40048234))) // Power-down states after wake-up from Deep-sleep mode +#define SCB_PDRUNCFG (*(pREG32 (0x40048238))) // Power-down configuration register +#define SCB_DEVICEID (*(pREG32 (0x400483F4))) // Device ID +#define SCB_MMFAR (*(pREG32 (0xE000ED34))) // Memory Manage Address Register (MMAR) +#define SCB_BFAR (*(pREG32 (0xE000ED38))) // Bus Fault Manage Address Register (BFAR) +#define SCB_DEMCR (*(pREG32 (0xE000EDFC))) + +/* CPU ID Base Register */ +#define SCB_CPUID (*(pREG32 (0xE000ED00))) +#define SCB_CPUID_REVISION_MASK ((unsigned int) 0x0000000F) // Revision Code +#define SCB_CPUID_PARTNO_MASK ((unsigned int) 0x0000FFF0) // Part Number +#define SCB_CPUID_CONSTANT_MASK ((unsigned int) 0x000F0000) // Constant +#define SCB_CPUID_VARIANT_MASK ((unsigned int) 0x00F00000) // Variant +#define SCB_CPUID_IMPLEMENTER_MASK ((unsigned int) 0xFF000000) // Implementer + +/* System Control Register */ + +#define SCB_SCR (*(pREG32 (0xE000ED10))) +#define SCB_SCR_SLEEPONEXIT_MASK ((unsigned int) 0x00000002) // Enable sleep on exit +#define SCB_SCR_SLEEPONEXIT ((unsigned int) 0x00000002) +#define SCB_SCR_SLEEPDEEP_MASK ((unsigned int) 0x00000004) +#define SCB_SCR_SLEEPDEEP ((unsigned int) 0x00000004) // Enable deep sleep +#define SCB_SCR_SEVONPEND_MASK ((unsigned int) 0x00000010) // Wake up from WFE is new int is pended regardless of priority +#define SCB_SCR_SEVONPEND ((unsigned int) 0x00000010) + +/* Application Interrupt and Reset Control Register */ + +#define SCB_AIRCR (*(pREG32 (0xE000ED0C))) +#define SCB_AIRCR_VECTKEY_VALUE ((unsigned int) 0x05FA0000) // Vect key needs to be set to 05FA for reset to work +#define SCB_AIRCR_VECTKEY_MASK ((unsigned int) 0xFFFF0000) +#define SCB_AIRCR_ENDIANESS ((unsigned int) 0x00008000) // Read Endianness (1=Big, 0=Little) +#define SCB_AIRCR_ENDIANESS_MASK ((unsigned int) 0x00008000) +#define SCB_AIRCR_PRIGROUP ((unsigned int) 0x00000700) +#define SCB_AIRCR_PRIGROUP_MASK ((unsigned int) 0x00000700) +#define SCB_AIRCR_SYSRESETREQ ((unsigned int) 0x00000004) // Request system reset +#define SCB_AIRCR_SYSRESETREQ_MASK ((unsigned int) 0x00000004) +#define SCB_AIRCR_VECTCLRACTIVE ((unsigned int) 0x00000002) // Used to prevent accidental reset +#define SCB_AIRCR_VECTCLRACTIVE_MASK ((unsigned int) 0x00000002) +#define SCB_AIRCR_VECTRESET ((unsigned int) 0x00000001) +#define SCB_AIRCR_VECTRESET_MASK ((unsigned int) 0x00000001) + +/* Memory Management Fault Status Register */ + +#define SCB_MMFSR (*(pREG32 (0xE000ED28))) +#define SCB_MMFSR_IACCVIOL_MASK ((unsigned int) 0x00000001) // Instruction access violation +#define SCB_MMFSR_IACCVIOL ((unsigned int) 0x00000001) +#define SCB_MMFSR_DACCVIOL_MASK ((unsigned int) 0x00000002) // Data access violation +#define SCB_MMFSR_DACCVIOL ((unsigned int) 0x00000002) +#define SCB_MMFSR_MUNSTKERR_MASK ((unsigned int) 0x00000008) // Unstacking error +#define SCB_MMFSR_MUNSTKERR ((unsigned int) 0x00000008) +#define SCB_MMFSR_MSTKERR_MASK ((unsigned int) 0x00000010) // Stacking error +#define SCB_MMFSR_MSTKERR ((unsigned int) 0x00000010) +#define SCB_MMFSR_MMARVALID_MASK ((unsigned int) 0x00000080) // Indicates MMAR is valid +#define SCB_MMFSR_MMARVALID ((unsigned int) 0x00000080) + +/* Bus Fault Status Register */ + +#define SCB_BFSR (*(pREG32 (0xE000ED29))) +#define SCB_BFSR_IBUSERR_MASK ((unsigned int) 0x00000001) // Instruction access violation +#define SCB_BFSR_IBUSERR ((unsigned int) 0x00000001) +#define SCB_BFSR_PRECISERR_MASK ((unsigned int) 0x00000002) // Precise data access violation +#define SCB_BFSR_PRECISERR ((unsigned int) 0x00000002) +#define SCB_BFSR_IMPRECISERR_MASK ((unsigned int) 0x00000004) // Imprecise data access violation +#define SCB_BFSR_IMPRECISERR ((unsigned int) 0x00000004) +#define SCB_BFSR_UNSTKERR_MASK ((unsigned int) 0x00000008) // Unstacking error +#define SCB_BFSR_UNSTKERR ((unsigned int) 0x00000008) +#define SCB_BFSR_STKERR_MASK ((unsigned int) 0x00000010) // Stacking error +#define SCB_BFSR_STKERR ((unsigned int) 0x00000010) +#define SCB_BFSR_BFARVALID_MASK ((unsigned int) 0x00000080) // Indicates BFAR is valid +#define SCB_BFSR_BFARVALID ((unsigned int) 0x00000080) + +/* Usage Fault Status Register */ + +#define SCB_UFSR (*(pREG32 (0xE000ED2A))) +#define SCB_UFSR_UNDEFINSTR_MASK ((unsigned int) 0x00000001) // Attempt to execute an undefined instruction +#define SCB_UFSR_UNDEFINSTR ((unsigned int) 0x00000001) +#define SCB_UFSR_INVSTATE_MASK ((unsigned int) 0x00000002) // Attempt to switch to invalid state (i.e. ARM) +#define SCB_UFSR_INVSTATE ((unsigned int) 0x00000002) +#define SCB_UFSR_INVPC_MASK ((unsigned int) 0x00000004) // Attempt to do exception with bad value in EXC_RETURN number +#define SCB_UFSR_INVPC ((unsigned int) 0x00000004) +#define SCB_UFSR_NOCP_MASK ((unsigned int) 0x00000008) // Attempt to execute a coprocessor instruction +#define SCB_UFSR_NOCP ((unsigned int) 0x00000008) +#define SCB_UFSR_UNALIGNED_MASK ((unsigned int) 0x00000100) // Unaligned access +#define SCB_UFSR_UNALIGNED ((unsigned int) 0x00000100) +#define SCB_UFSR_DIVBYZERO_MASK ((unsigned int) 0x00000200) // Divide by zero +#define SCB_UFSR_DIVBYZERO ((unsigned int) 0x00000200) + +/* Hard Fault Status Register */ + +#define SCB_HFSR (*(pREG32 (0xE000ED2C))) +#define SCB_HFSR_VECTTBL_MASK ((unsigned int) 0x00000002) // Hard fault caused by failed vector fetch +#define SCB_HFSR_VECTTBL ((unsigned int) 0x00000002) +#define SCB_HFSR_FORCED_MASK ((unsigned int) 0x40000000) // Hard fault taken because of bus/mem man/usage fault +#define SCB_HFSR_FORCED ((unsigned int) 0x40000000) +#define SCB_HFSR_DEBUGEVT_MASK ((unsigned int) 0x80000000) // Hard fault triggered by debug event +#define SCB_HFSR_DEBUGEVT ((unsigned int) 0x80000000) + +/* Debug Fault Status Register */ + +#define SCB_DFSR (*(pREG32 (0xE000ED30))) +#define SCB_DFSR_HALTED_MASK ((unsigned int) 0x00000001) // Halt requested in NVIC +#define SCB_DFSR_HALTED ((unsigned int) 0x00000001) +#define SCB_DFSR_BKPT_MASK ((unsigned int) 0x00000002) // BKPT instruction executed +#define SCB_DFSR_BKPT ((unsigned int) 0x00000002) +#define SCB_DFSR_DWTTRAP_MASK ((unsigned int) 0x00000004) // DWT match occurred +#define SCB_DFSR_DWTTRAP ((unsigned int) 0x00000004) +#define SCB_DFSR_VCATCH_MASK ((unsigned int) 0x00000008) // Vector fetch occurred +#define SCB_DFSR_VCATCH ((unsigned int) 0x00000008) +#define SCB_DFSR_EXTERNAL_MASK ((unsigned int) 0x00000010) // EDBGRQ signal asserted +#define SCB_DFSR_EXTERNAL ((unsigned int) 0x00000010) + +/* SCB_MEMREMAP (System memory remap register) + The system memory remap register selects whether the ARM interrupt vectors are read + from the boot ROM, the flash, or the SRAM. */ + +#define SCB_MEMREMAP_MODE_BOOTLOADER ((unsigned int) 0x00000000) // Interrupt vectors are remapped to Boot ROM +#define SCB_MEMREMAP_MODE_RAM ((unsigned int) 0x00000001) // Interrupt vectors are remapped to Static ROM +#define SCB_MEMREMAP_MODE_FLASH ((unsigned int) 0x00000002) // Interrupt vectors are not remapped and reside in Flash +#define SCB_MEMREMAP_MASK ((unsigned int) 0x00000003) + +/* PRESETCTRL (Peripheral reset control register) */ + +#define SCB_PRESETCTRL_SSP0_RESETENABLED ((unsigned int) 0x00000000) +#define SCB_PRESETCTRL_SSP0_RESETDISABLED ((unsigned int) 0x00000001) +#define SCB_PRESETCTRL_SSP0_MASK ((unsigned int) 0x00000001) +#define SCB_PRESETCTRL_I2C_RESETENABLED ((unsigned int) 0x00000000) +#define SCB_PRESETCTRL_I2C_RESETDISABLED ((unsigned int) 0x00000002) +#define SCB_PRESETCTRL_I2C_MASK ((unsigned int) 0x00000002) + +/* SYSPLLCTRL (System PLL control register) + This register connects and enables the system PLL and configures the PLL multiplier and + divider values. The PLL accepts an input frequency from 10 MHz to 25 MHz from various + clock sources. The input frequency is multiplied up to a high frequency, then divided down + to provide the actual clock used by the CPU, peripherals, and optionally the USB + subsystem. Note that the USB subsystem has its own dedicated PLL. The PLL can + produce a clock up to the maximum allowed for the CPU, which is 72 MHz. */ + +#define SCB_PLLCTRL_MULT_1 ((unsigned int) 0x00000000) +#define SCB_PLLCTRL_MULT_2 ((unsigned int) 0x00000001) +#define SCB_PLLCTRL_MULT_3 ((unsigned int) 0x00000002) +#define SCB_PLLCTRL_MULT_4 ((unsigned int) 0x00000003) +#define SCB_PLLCTRL_MULT_5 ((unsigned int) 0x00000004) +#define SCB_PLLCTRL_MULT_6 ((unsigned int) 0x00000005) +#define SCB_PLLCTRL_MULT_7 ((unsigned int) 0x00000006) +#define SCB_PLLCTRL_MULT_8 ((unsigned int) 0x00000007) +#define SCB_PLLCTRL_MULT_9 ((unsigned int) 0x00000008) +#define SCB_PLLCTRL_MULT_10 ((unsigned int) 0x00000009) +#define SCB_PLLCTRL_MULT_11 ((unsigned int) 0x0000000A) +#define SCB_PLLCTRL_MULT_12 ((unsigned int) 0x0000000B) +#define SCB_PLLCTRL_MULT_13 ((unsigned int) 0x0000000C) +#define SCB_PLLCTRL_MULT_14 ((unsigned int) 0x0000000D) +#define SCB_PLLCTRL_MULT_15 ((unsigned int) 0x0000000E) +#define SCB_PLLCTRL_MULT_16 ((unsigned int) 0x0000000F) +#define SCB_PLLCTRL_MULT_17 ((unsigned int) 0x00000010) +#define SCB_PLLCTRL_MULT_18 ((unsigned int) 0x00000011) +#define SCB_PLLCTRL_MULT_19 ((unsigned int) 0x00000012) +#define SCB_PLLCTRL_MULT_20 ((unsigned int) 0x00000013) +#define SCB_PLLCTRL_MULT_21 ((unsigned int) 0x00000014) +#define SCB_PLLCTRL_MULT_22 ((unsigned int) 0x00000015) +#define SCB_PLLCTRL_MULT_23 ((unsigned int) 0x00000016) +#define SCB_PLLCTRL_MULT_24 ((unsigned int) 0x00000017) +#define SCB_PLLCTRL_MULT_25 ((unsigned int) 0x00000018) +#define SCB_PLLCTRL_MULT_26 ((unsigned int) 0x00000019) +#define SCB_PLLCTRL_MULT_27 ((unsigned int) 0x0000001A) +#define SCB_PLLCTRL_MULT_28 ((unsigned int) 0x0000001B) +#define SCB_PLLCTRL_MULT_29 ((unsigned int) 0x0000001C) +#define SCB_PLLCTRL_MULT_30 ((unsigned int) 0x0000001D) +#define SCB_PLLCTRL_MULT_31 ((unsigned int) 0x0000001E) +#define SCB_PLLCTRL_MULT_32 ((unsigned int) 0x0000001F) +#define SCB_PLLCTRL_MULT_MASK ((unsigned int) 0x0000001F) +#define SCB_PLLCTRL_DIV_2 ((unsigned int) 0x00000000) +#define SCB_PLLCTRL_DIV_4 ((unsigned int) 0x00000020) +#define SCB_PLLCTRL_DIV_8 ((unsigned int) 0x00000040) +#define SCB_PLLCTRL_DIV_16 ((unsigned int) 0x00000060) +#define SCB_PLLCTRL_DIV_BIT (5) +#define SCB_PLLCTRL_DIV_MASK ((unsigned int) 0x00000060) +#define SCB_PLLCTRL_DIRECT_MASK ((unsigned int) 0x00000080) // Direct CCO clock output control +#define SCB_PLLCTRL_BYPASS_MASK ((unsigned int) 0x00000100) // Input clock bypass control +#define SCB_PLLCTRL_MASK ((unsigned int) 0x000001FF) + +/* SYSPLLSTAT (System PLL status register) + This register is a Read-only register and supplies the PLL lock status */ + +#define SCB_PLLSTAT_LOCK ((unsigned int) 0x00000001) // 0 = PLL not locked, 1 = PLL locked +#define SCB_PLLSTAT_LOCK_MASK ((unsigned int) 0x00000001) + +/* USBPLLCTRL (USB PLL control register) + The USB PLL is identical to the system PLL and is used to provide a dedicated clock to + the USB block if available. The USB PLL should be always connected to the system + oscillator to produce a stable USB clock. */ + +#define SCB_USBPLLCTRL_MULT_1 ((unsigned int) 0x00000000) +#define SCB_USBPLLCTRL_MULT_2 ((unsigned int) 0x00000001) +#define SCB_USBPLLCTRL_MULT_3 ((unsigned int) 0x00000002) +#define SCB_USBPLLCTRL_MULT_4 ((unsigned int) 0x00000003) +#define SCB_USBPLLCTRL_MULT_5 ((unsigned int) 0x00000004) +#define SCB_USBPLLCTRL_MULT_6 ((unsigned int) 0x00000005) +#define SCB_USBPLLCTRL_MULT_7 ((unsigned int) 0x00000006) +#define SCB_USBPLLCTRL_MULT_8 ((unsigned int) 0x00000007) +#define SCB_USBPLLCTRL_MULT_9 ((unsigned int) 0x00000008) +#define SCB_USBPLLCTRL_MULT_10 ((unsigned int) 0x00000009) +#define SCB_USBPLLCTRL_MULT_11 ((unsigned int) 0x0000000A) +#define SCB_USBPLLCTRL_MULT_12 ((unsigned int) 0x0000000B) +#define SCB_USBPLLCTRL_MULT_13 ((unsigned int) 0x0000000C) +#define SCB_USBPLLCTRL_MULT_14 ((unsigned int) 0x0000000D) +#define SCB_USBPLLCTRL_MULT_15 ((unsigned int) 0x0000000E) +#define SCB_USBPLLCTRL_MULT_16 ((unsigned int) 0x0000000F) +#define SCB_USBPLLCTRL_MULT_17 ((unsigned int) 0x00000010) +#define SCB_USBPLLCTRL_MULT_18 ((unsigned int) 0x00000011) +#define SCB_USBPLLCTRL_MULT_19 ((unsigned int) 0x00000012) +#define SCB_USBPLLCTRL_MULT_20 ((unsigned int) 0x00000013) +#define SCB_USBPLLCTRL_MULT_21 ((unsigned int) 0x00000014) +#define SCB_USBPLLCTRL_MULT_22 ((unsigned int) 0x00000015) +#define SCB_USBPLLCTRL_MULT_23 ((unsigned int) 0x00000016) +#define SCB_USBPLLCTRL_MULT_24 ((unsigned int) 0x00000017) +#define SCB_USBPLLCTRL_MULT_25 ((unsigned int) 0x00000018) +#define SCB_USBPLLCTRL_MULT_26 ((unsigned int) 0x00000019) +#define SCB_USBPLLCTRL_MULT_27 ((unsigned int) 0x0000001A) +#define SCB_USBPLLCTRL_MULT_28 ((unsigned int) 0x0000001B) +#define SCB_USBPLLCTRL_MULT_29 ((unsigned int) 0x0000001C) +#define SCB_USBPLLCTRL_MULT_30 ((unsigned int) 0x0000001D) +#define SCB_USBPLLCTRL_MULT_31 ((unsigned int) 0x0000001E) +#define SCB_USBPLLCTRL_MULT_32 ((unsigned int) 0x0000001F) +#define SCB_USBPLLCTRL_MULT_MASK ((unsigned int) 0x0000001F) +#define SCB_USBPLLCTRL_DIV_2 ((unsigned int) 0x00000000) +#define SCB_USBPLLCTRL_DIV_4 ((unsigned int) 0x00000020) +#define SCB_USBPLLCTRL_DIV_8 ((unsigned int) 0x00000040) +#define SCB_USBPLLCTRL_DIV_16 ((unsigned int) 0x00000060) +#define SCB_USBPLLCTRL_DIV_BIT (5) +#define SCB_USBPLLCTRL_DIV_MASK ((unsigned int) 0x00000060) +#define SCB_USBPLLCTRL_DIRECT_MASK ((unsigned int) 0x00000080) // Direct CCO clock output control +#define SCB_USBPLLCTRL_BYPASS_MASK ((unsigned int) 0x00000100) // Input clock bypass control +#define SCB_USBPLLCTRL_MASK ((unsigned int) 0x000001FF) + +/* USBPLLSTAT (System PLL status register) + This register is a Read-only register and supplies the PLL lock status. */ + +#define SCB_USBPLLSTAT_LOCK ((unsigned int) 0x00000001) // 0 = PLL not locked, 1 = PLL locked +#define SCB_USBPLLSTAT_LOCK_MASK ((unsigned int) 0x00000001) + +/* SYSOSCCTRL (System oscillator control register) + This register configures the frequency range for the system oscillator. */ + +#define SCB_SYSOSCCTRL_BYPASS_DISABLED ((unsigned int) 0x00000000) // Oscillator is not bypassed. +#define SCB_SYSOSCCTRL_BYPASS_ENABLED ((unsigned int) 0x00000001) // Bypass enabled +#define SCB_SYSOSCCTRL_BYPASS_MASK ((unsigned int) 0x00000001) +#define SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ ((unsigned int) 0x00000000) // 1-20 MHz frequency range +#define SCB_SYSOSCCTRL_FREQRANGE_15TO25MHZ ((unsigned int) 0x00000002) // 15-25 MHz frequency range +#define SCB_SYSOSCCTRL_FREQRANGE_MASK ((unsigned int) 0x00000002) + +/* WDTOSCTRL (Watchdog oscillator control register) + This register configures the watchdog oscillator. The oscillator consists of an analog and a + digital part. The analog part contains the oscillator function and generates an analog clock + (Fclkana). With the digital part, the analog output clock (Fclkana) can be divided to the + required output clock frequency wdt_osc_clk. The analog output frequency (Fclkana) can + be adjusted with the FREQSEL bits between 500 kHz and 3.7 MHz. With the digital part + Fclkana will be divided (divider ratios = 2, 4,...,64) to wdt_osc_clk using the DIVSEL bits.*/ + +#define SCB_WDTOSCCTRL_DIVSEL_DIV2 ((unsigned int) 0x00000000) // Reset value +#define SCB_WDTOSCCTRL_DIVSEL_DIV4 ((unsigned int) 0x00000001) +#define SCB_WDTOSCCTRL_DIVSEL_DIV6 ((unsigned int) 0x00000002) +#define SCB_WDTOSCCTRL_DIVSEL_DIV8 ((unsigned int) 0x00000003) +#define SCB_WDTOSCCTRL_DIVSEL_DIV10 ((unsigned int) 0x00000004) +#define SCB_WDTOSCCTRL_DIVSEL_DIV12 ((unsigned int) 0x00000005) +#define SCB_WDTOSCCTRL_DIVSEL_DIV14 ((unsigned int) 0x00000006) +#define SCB_WDTOSCCTRL_DIVSEL_DIV16 ((unsigned int) 0x00000007) +#define SCB_WDTOSCCTRL_DIVSEL_DIV18 ((unsigned int) 0x00000008) +#define SCB_WDTOSCCTRL_DIVSEL_DIV20 ((unsigned int) 0x00000009) +#define SCB_WDTOSCCTRL_DIVSEL_DIV22 ((unsigned int) 0x0000000A) +#define SCB_WDTOSCCTRL_DIVSEL_DIV24 ((unsigned int) 0x0000000B) +#define SCB_WDTOSCCTRL_DIVSEL_DIV26 ((unsigned int) 0x0000000C) +#define SCB_WDTOSCCTRL_DIVSEL_DIV28 ((unsigned int) 0x0000000D) +#define SCB_WDTOSCCTRL_DIVSEL_DIV30 ((unsigned int) 0x0000000E) +#define SCB_WDTOSCCTRL_DIVSEL_DIV32 ((unsigned int) 0x0000000F) +#define SCB_WDTOSCCTRL_DIVSEL_DIV34 ((unsigned int) 0x00000010) +#define SCB_WDTOSCCTRL_DIVSEL_DIV36 ((unsigned int) 0x00000011) +#define SCB_WDTOSCCTRL_DIVSEL_DIV38 ((unsigned int) 0x00000012) +#define SCB_WDTOSCCTRL_DIVSEL_DIV40 ((unsigned int) 0x00000013) +#define SCB_WDTOSCCTRL_DIVSEL_DIV42 ((unsigned int) 0x00000014) +#define SCB_WDTOSCCTRL_DIVSEL_DIV44 ((unsigned int) 0x00000015) +#define SCB_WDTOSCCTRL_DIVSEL_DIV46 ((unsigned int) 0x00000016) +#define SCB_WDTOSCCTRL_DIVSEL_DIV48 ((unsigned int) 0x00000017) +#define SCB_WDTOSCCTRL_DIVSEL_DIV50 ((unsigned int) 0x00000018) +#define SCB_WDTOSCCTRL_DIVSEL_DIV52 ((unsigned int) 0x00000019) +#define SCB_WDTOSCCTRL_DIVSEL_DIV54 ((unsigned int) 0x0000001A) +#define SCB_WDTOSCCTRL_DIVSEL_DIV56 ((unsigned int) 0x0000001B) +#define SCB_WDTOSCCTRL_DIVSEL_DIV58 ((unsigned int) 0x0000001C) +#define SCB_WDTOSCCTRL_DIVSEL_DIV60 ((unsigned int) 0x0000001D) +#define SCB_WDTOSCCTRL_DIVSEL_DIV62 ((unsigned int) 0x0000001E) +#define SCB_WDTOSCCTRL_DIVSEL_DIV64 ((unsigned int) 0x0000001F) +#define SCB_WDTOSCCTRL_DIVSEL_MASK ((unsigned int) 0x0000001F) +#define SCB_WDTOSCCTRL_FREQSEL_0_5MHZ ((unsigned int) 0x00000020) +#define SCB_WDTOSCCTRL_FREQSEL_0_8MHZ ((unsigned int) 0x00000040) +#define SCB_WDTOSCCTRL_FREQSEL_1_1MHZ ((unsigned int) 0x00000060) +#define SCB_WDTOSCCTRL_FREQSEL_1_4MHZ ((unsigned int) 0x00000080) +#define SCB_WDTOSCCTRL_FREQSEL_1_6MHZ ((unsigned int) 0x000000A0) // Reset value +#define SCB_WDTOSCCTRL_FREQSEL_1_8MHZ ((unsigned int) 0x000000C0) +#define SCB_WDTOSCCTRL_FREQSEL_2_0MHZ ((unsigned int) 0x000000E0) +#define SCB_WDTOSCCTRL_FREQSEL_2_2MHZ ((unsigned int) 0x00000100) +#define SCB_WDTOSCCTRL_FREQSEL_2_4MHZ ((unsigned int) 0x00000120) +#define SCB_WDTOSCCTRL_FREQSEL_2_6MHZ ((unsigned int) 0x00000140) +#define SCB_WDTOSCCTRL_FREQSEL_2_7MHZ ((unsigned int) 0x00000160) +#define SCB_WDTOSCCTRL_FREQSEL_2_9MHZ ((unsigned int) 0x00000180) +#define SCB_WDTOSCCTRL_FREQSEL_3_1MHZ ((unsigned int) 0x000001A0) +#define SCB_WDTOSCCTRL_FREQSEL_3_2MHZ ((unsigned int) 0x000001C0) +#define SCB_WDTOSCCTRL_FREQSEL_3_4MHZ ((unsigned int) 0x000001E0) +#define SCB_WDTOSCCTRL_FREQSEL_MASK ((unsigned int) 0x000001E0) + +/* IRCCTRL (Internal resonant crystal control register) + This register is used to trim the on-chip 12 MHz oscillator. The trim value is factory-preset + and written by the boot code on start-up. */ + +#define SCB_IRCCTRL_MASK ((unsigned int) 0x000000FF) + +/* SYSRSTSTAT (System reset status register) + The SYSRSTSTAT register shows the source of the latest reset event. The bits are + cleared by writing a one to any of the bits. The POR event clears all other bits in this + register, but if another reset signal (e.g., EXTRST) remains asserted after the POR signal + is negated, then its bit is set to detected. */ + +#define SCB_RESETSTAT_POR_MASK ((unsigned int) 0x00000001) // POR reset status +#define SCB_RESETSTAT_EXTRST_MASK ((unsigned int) 0x00000002) // Status of the external reset pin +#define SCB_RESETSTAT_WDT_MASK ((unsigned int) 0x00000004) // Status of the watchdog reset +#define SCB_RESETSTAT_BOD_MASK ((unsigned int) 0x00000008) // Status of the brown-out detect reset +#define SCB_RESETSTAT_SYSRST_MASK ((unsigned int) 0x00000010) // Status of the software system reset +#define SCB_RESETSTAT_MASK ((unsigned int) 0x00000010) + +/* SYSPLLCLKSEL (System PLL clock source select register) + This register selects the clock source for the system PLL. The SYSPLLCLKUEN register + must be toggled from LOW to HIGH for the update to take effect. + Remark: The system oscillator must be selected if the system PLL is used to generate a + 48 MHz clock to the USB block. +*/ + +#define SCB_CLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) +#define SCB_CLKSEL_SOURCE_MAINOSC ((unsigned int) 0x00000001) +#define SCB_CLKSEL_SOURCE_RTCOSC ((unsigned int) 0x00000002) +#define SCB_CLKSEL_SOURCE_MASK ((unsigned int) 0x00000002) + +/* SYSPLLUEN (System PLL clock source update enable register) + This register updates the clock source of the system PLL with the new input clock after the + SYSPLLCLKSEL register has been written to. In order for the update to take effect, first + write a zero to the SYSPLLUEN register and then write a one to SYSPLLUEN. */ + +#define SCB_PLLCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_PLLCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_PLLCLKUEN_MASK ((unsigned int) 0x00000001) + +/* USBPLLCLKSEL (USB PLL clock source select register) + his register selects the clock source for the dedicated USB PLL. The SYSPLLCLKUEN + register must be toggled from LOW to HIGH for the update to take effect. + Remark: Always select the system oscillator to produce a stable 48 MHz clock for + the USB block. */ + +#define SCB_USBPLLCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Do NOT use (even though this is the default value) +#define SCB_USBPLLCLKSEL_SOURCE_MAINOSC ((unsigned int) 0x00000001) // Main oscillator should always be used for USB clock +#define SCB_USBPLLCLKSEL_SOURCE_MASK ((unsigned int) 0x00000002) + +/* USBPLLUEN (USB PLL clock source update enable register) + This register updates the clock source of the USB PLL with the new input clock after the + USBPLLCLKSEL register has been written to. In order for the update to take effect at the + USB PLL input, first write a zero to the USBPLLUEN register and then write a one to + USBPLLUEN. */ + +#define SCB_USBPLLCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBPLLCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_USBPLLCLKUEN_MASK ((unsigned int) 0x00000001) + +/* MAINCLKSEL (Main clock source select register) + This register selects the main system clock which can be either the output from the + system PLL or the IRC, system, or Watchdog oscillators directly. The main system clock + clocks the core, the peripherals, and optionally the USB block. + The MAINCLKUEN register must be toggled from LOW to HIGH for the update to take effect.*/ + +#define SCB_MAINCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Use IRC oscillator for main clock source +#define SCB_MAINCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use Input clock to system PLL for main clock source +#define SCB_MAINCLKSEL_SOURCE_WDTOSC ((unsigned int) 0x00000002) // Use watchdog oscillator for main clock source +#define SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT ((unsigned int) 0x00000003) // Use system PLL clock out for main clock source +#define SCB_MAINCLKSEL_MASK ((unsigned int) 0x00000003) + +/* MAINCLKUEN (Main clock source update enable register) + This register updates the clock source of the main clock with the new input clock after the + MAINCLKSEL register has been written to. In order for the update to take effect, first write + a zero to the MAINUEN register and then write a one to MAINCLKUEN. */ + +#define SCB_MAINCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_MAINCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_MAINCLKUEN_MASK ((unsigned int) 0x00000001) + +/* SYSAHBCLKDIV (System AHB clock divider register) + This register divides the main clock to provide the system clock to the core, memories, + and the peripherals. The system clock can be shut down completely by setting the DIV + bits to 0x0. */ + +#define SCB_SYSAHBCLKDIV_DISABLE ((unsigned int) 0x00000000) // 0 will shut the system clock down completely +#define SCB_SYSAHBCLKDIV_DIV1 ((unsigned int) 0x00000001) // 1, 2 or 4 are the most common values +#define SCB_SYSAHBCLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_SYSAHBCLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_SYSAHBCLKDIV_MASK ((unsigned int) 0x000000FF) // AHB clock divider can be from 0 to 255 + +/* AHBCLKCTRL (System AHB clock control register) + The AHBCLKCTRL register enables the clocks to individual system and peripheral blocks. + The system clock (sys_ahb_clk[0], bit 0 in the AHBCLKCTRL register) provides the clock + for the AHB to APB bridge, the AHB matrix, the ARM Cortex-M3, the Syscon block, and + the PMU. This clock cannot be disabled. */ + +#define SCB_SYSAHBCLKCTRL_SYS ((unsigned int) 0x00000001) // Enables clock for AHB and APB bridges, FCLK, HCLK, SysCon and PMU +#define SCB_SYSAHBCLKCTRL_SYS_MASK ((unsigned int) 0x00000001) +#define SCB_SYSAHBCLKCTRL_ROM ((unsigned int) 0x00000002) // Enables clock for ROM +#define SCB_SYSAHBCLKCTRL_ROM_MASK ((unsigned int) 0x00000002) +#define SCB_SYSAHBCLKCTRL_RAM ((unsigned int) 0x00000004) // Enables clock for SRAM +#define SCB_SYSAHBCLKCTRL_RAM_MASK ((unsigned int) 0x00000004) +#define SCB_SYSAHBCLKCTRL_FLASH1 ((unsigned int) 0x00000008) // Enables clock for flash1 +#define SCB_SYSAHBCLKCTRL_FLASH1_MASK ((unsigned int) 0x00000008) +#define SCB_SYSAHBCLKCTRL_FLASH2 ((unsigned int) 0x00000010) // Enables clock for flash2 +#define SCB_SYSAHBCLKCTRL_FLASH2_MASK ((unsigned int) 0x00000010) +#define SCB_SYSAHBCLKCTRL_I2C ((unsigned int) 0x00000020) // Enables clock for I2C +#define SCB_SYSAHBCLKCTRL_I2C_MASK ((unsigned int) 0x00000020) +#define SCB_SYSAHBCLKCTRL_GPIO ((unsigned int) 0x00000040) // Enables clock for GPIO +#define SCB_SYSAHBCLKCTRL_GPIO_MASK ((unsigned int) 0x00000040) +#define SCB_SYSAHBCLKCTRL_CT16B0 ((unsigned int) 0x00000080) // Enables clock for 16-bit counter/timer 0 +#define SCB_SYSAHBCLKCTRL_CT16B0_MASK ((unsigned int) 0x00000080) +#define SCB_SYSAHBCLKCTRL_CT16B1 ((unsigned int) 0x00000100) // Enables clock for 16-bit counter/timer 1 +#define SCB_SYSAHBCLKCTRL_CT16B1_MASK ((unsigned int) 0x00000100) +#define SCB_SYSAHBCLKCTRL_CT32B0 ((unsigned int) 0x00000200) // Enables clock for 32-bit counter/timer 0 +#define SCB_SYSAHBCLKCTRL_CT32B0_MASK ((unsigned int) 0x00000200) +#define SCB_SYSAHBCLKCTRL_CT32B1 ((unsigned int) 0x00000400) // Enables clock for 32-bit counter/timer 1 +#define SCB_SYSAHBCLKCTRL_CT32B1_MASK ((unsigned int) 0x00000400) +#define SCB_SYSAHBCLKCTRL_SSP0 ((unsigned int) 0x00000800) // Enables clock for SSP0 +#define SCB_SYSAHBCLKCTRL_SSP0_MASK ((unsigned int) 0x00000800) +#define SCB_SYSAHBCLKCTRL_UART ((unsigned int) 0x00001000) // Enables clock for UART. UART pins must be configured +#define SCB_SYSAHBCLKCTRL_UART_MASK ((unsigned int) 0x00001000) // in the IOCON block before the UART clock can be enabled. +#define SCB_SYSAHBCLKCTRL_ADC ((unsigned int) 0x00002000) // Enables clock for ADC +#define SCB_SYSAHBCLKCTRL_ADC_MASK ((unsigned int) 0x00002000) +#define SCB_SYSAHBCLKCTRL_USB_REG ((unsigned int) 0x00004000) // Enables clock for USB_REG +#define SCB_SYSAHBCLKCTRL_USB_REG_MASK ((unsigned int) 0x00004000) +#define SCB_SYSAHBCLKCTRL_WDT ((unsigned int) 0x00008000) // Enables clock for watchdog timer +#define SCB_SYSAHBCLKCTRL_WDT_MASK ((unsigned int) 0x00008000) +#define SCB_SYSAHBCLKCTRL_IOCON ((unsigned int) 0x00010000) // Enables clock for IO configuration block +#define SCB_SYSAHBCLKCTRL_IOCON_MASK ((unsigned int) 0x00010000) +#define SCB_SYSAHBCLKCTRL_ALL_MASK ((unsigned int) 0x0001FFFF) + +/* SSP0CLKDIV (SSP0 clock divider register) + This register configures the SSP0 peripheral clock SSP_PCLK. The SSP_PCLK can be + shut down by setting the DIV bits to 0x0. It can be set from 1..255. */ + +#define SCB_SSP0CLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_SSP0CLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide SSP0 clock by 1 (can be set from 1..255) +#define SCB_SSP0CLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_SSP0CLKDIV_DIV3 ((unsigned int) 0x00000003) +#define SCB_SSP0CLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_SSP0CLKDIV_DIV6 ((unsigned int) 0x00000006) +#define SCB_SSP0CLKDIV_DIV10 ((unsigned int) 0x0000000A) +#define SCB_SSP0CLKDIV_DIV12 ((unsigned int) 0x0000000C) +#define SCB_SSP0CLKDIV_DIV20 ((unsigned int) 0x00000014) +#define SCB_SSP0CLKDIV_DIV40 ((unsigned int) 0x00000028) +#define SCB_SSP0CLKDIV_MASK ((unsigned int) 0x000000FF) + +/* UARTCLKDIV (UART clock divider register) + This register configures the UART peripheral. The UART_PCLK can be shut down by + setting the DIV bits to 0x0. + Remark: Note that the UART pins must be configured in the IOCON block before the + UART clock can be enabled. */ + +#define SCB_UARTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_UARTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide UART clock by 1 (can be set from 1..255) +#define SCB_UARTCLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_UARTCLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_UARTCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* SYSTICKCLKDIV (SYSTICK clock divider register) + This register configures the SYSTICK peripheral clock. The SYSTICK timer clock can be + shut down by setting the DIV bits to 0x0. */ + +#define SCB_SYSTICKCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_SYSTICKCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide SYSTICK clock by 1 (can be set from 1..255) +#define SCB_SYSTICKCLKDIV_DIV2 ((unsigned int) 0x00000002) // Divide SYSTICK clock by 2 +#define SCB_SYSTICKCLKDIV_DIV4 ((unsigned int) 0x00000004) // Divide SYSTICK clock by 4 +#define SCB_SYSTICKCLKDIV_DIV8 ((unsigned int) 0x00000008) // Divide SYSTICK clock by 8 +#define SCB_SYSTICKCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* USBCLKSEL (USB clock source select register) + This register selects the clock source for the USB usb_clk. The clock source can be either + the USB PLL output or the main clock, and the clock can be further divided by the + USBCLKDIV register to obtain a 48 MHz clock. The USBCLKUEN register must be toggled from + LOW to HIGH for the update to take effect. */ + +#define SCB_USBCLKSEL_SOURCE_USBPLLOUT ((unsigned int) 0x00000000) // USB PLL output +#define SCB_USBCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_USBCLKSEL_MASK ((unsigned int) 0x00000003) + +/* USBCLKUEN (USB clock source update enable register) + This register updates the clock source of the USB with the new input clock after the + USBCLKSEL register has been written to. In order for the update to take effect, first write + a zero to the USBCLKUEN register and then write a one to USBCLKUEN. */ + +#define SCB_USBCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_USBCLKUEN_MASK ((unsigned int) 0x00000001) + +/* USBCLKDIV (USB clock divider register) + This register allows the USB clock usb_clk to be divided to 48 MHz. The usb_clk can be + shut down by setting the DIV bits to 0x0. */ + +#define SCB_USBCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide USB clock by 1 (can be set from 1..255) +#define SCB_USBCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* WDTCLKSEL (WDT clock source select register) + This register selects the clock source for the watchdog timer. The WDTCLKUEN register + must be toggled from LOW to HIGH for the update to take effect. */ + +#define SCB_WDTCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Use the internal oscillator +#define SCB_WDTCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC ((unsigned int) 0x00000002) // Use the watchdog oscillator +#define SCB_WDTCLKSEL_MASK ((unsigned int) 0x00000003) + +/* WDTCLKUEN (WDT clock source update enable register) + This register updates the clock source of the watchdog timer with the new input clock after + the WDTCLKSEL register has been written to. In order for the update to take effect at the + input of the watchdog timer, first write a zero to the WDTCLKUEN register and then write + a one to WDTCLKUEN. */ + +#define SCB_WDTCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_WDTCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_WDTCLKUEN_MASK ((unsigned int) 0x00000001) + +/* WDTCLKDIV (WDT clock divider register) + This register determines the divider values for the watchdog clock wdt_clk. */ + +#define SCB_WDTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_WDTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide clock by 1 (can be set from 1..255) +#define SCB_WDTCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* CLKOUTCLKSEL (CLKOUT clock source select register) + This register configures the clkout_clk signal to be output on the CLKOUT pin. All three + oscillators and the main clock can be selected for the clkout_clk clock. + The CLKOUTCLKUEN register must be toggled from LOW to HIGH for the update to take effect. */ + +#define SCB_CLKOUTCLKSEL_SOURCE_USBPLLOUT ((unsigned int) 0x00000000) // USB PLL output +#define SCB_CLKOUTCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_CLKOUTCLKSEL_MASK ((unsigned int) 0x00000003) + +/* CLKOUTUEN (CLKOUT clock source update enable register) + This register updates the clock source of the CLKOUT pin with the new clock after the + CLKOUTCLKSEL register has been written to. In order for the update to take effect at the + input of the CLKOUT pin, first write a zero to the CLKCLKUEN register and then write a + one to CLKCLKUEN. */ + +#define SCB_CLKOUTCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_CLKOUTCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_CLKOUTCLKUEN_MASK ((unsigned int) 0x00000001) + +/* CLKOUTCLKDIV (CLKOUT clock divider register) + This register determines the divider value for the clkout_clk signal on the CLKOUT pin. */ + +#define SCB_CLKOUTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_CLKOUTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide clock by 1 (can be set from 1..255) +#define SCB_CLKOUTCLKDIV_MASK ((unsigned int) 0x000000FF) + + +/* PIOPORCAP0 (POR captured PIO status register 0) + The PIOPORCAP0 register captures the state (HIGH or LOW) of the PIO pins of ports 0,1, + and 2 (pins PIO2_0 to PIO2_7) at power-on-reset. Each bit represents the reset state of + one GPIO pin. This register is a read-only status register. */ + +#define SCB_PIOPORCAP0_PIO0_0 ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP0_PIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP0_PIO0_1 ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP0_PIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP0_PIO0_2 ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP0_PIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP0_PIO0_3 ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP0_PIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP0_PIO0_4 ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP0_PIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP0_PIO0_5 ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP0_PIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP0_PIO0_6 ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP0_PIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP0_PIO0_7 ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP0_PIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP0_PIO0_8 ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP0_PIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP0_PIO0_9 ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP0_PIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP0_PIO0_10 ((unsigned int) 0x00000400) +#define SCB_PIOPORCAP0_PIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_PIOPORCAP0_PIO0_11 ((unsigned int) 0x00000800) +#define SCB_PIOPORCAP0_PIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_PIOPORCAP0_PIO1_0 ((unsigned int) 0x00001000) +#define SCB_PIOPORCAP0_PIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_PIOPORCAP0_PIO1_1 ((unsigned int) 0x00002000) +#define SCB_PIOPORCAP0_PIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_PIOPORCAP0_PIO1_2 ((unsigned int) 0x00004000) +#define SCB_PIOPORCAP0_PIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_PIOPORCAP0_PIO1_3 ((unsigned int) 0x00008000) +#define SCB_PIOPORCAP0_PIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_PIOPORCAP0_PIO1_4 ((unsigned int) 0x00010000) +#define SCB_PIOPORCAP0_PIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_PIOPORCAP0_PIO1_5 ((unsigned int) 0x00020000) +#define SCB_PIOPORCAP0_PIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_PIOPORCAP0_PIO1_6 ((unsigned int) 0x00040000) +#define SCB_PIOPORCAP0_PIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_PIOPORCAP0_PIO1_7 ((unsigned int) 0x00080000) +#define SCB_PIOPORCAP0_PIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_PIOPORCAP0_PIO1_8 ((unsigned int) 0x00100000) +#define SCB_PIOPORCAP0_PIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_PIOPORCAP0_PIO1_9 ((unsigned int) 0x00200000) +#define SCB_PIOPORCAP0_PIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_PIOPORCAP0_PIO1_10 ((unsigned int) 0x00400000) +#define SCB_PIOPORCAP0_PIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_PIOPORCAP0_PIO1_11 ((unsigned int) 0x00800000) +#define SCB_PIOPORCAP0_PIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_PIOPORCAP0_PIO2_0 ((unsigned int) 0x01000000) +#define SCB_PIOPORCAP0_PIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_PIOPORCAP0_PIO2_1 ((unsigned int) 0x02000000) +#define SCB_PIOPORCAP0_PIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_PIOPORCAP0_PIO2_2 ((unsigned int) 0x04000000) +#define SCB_PIOPORCAP0_PIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_PIOPORCAP0_PIO2_3 ((unsigned int) 0x08000000) +#define SCB_PIOPORCAP0_PIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_PIOPORCAP0_PIO2_4 ((unsigned int) 0x10000000) +#define SCB_PIOPORCAP0_PIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_PIOPORCAP0_PIO2_5 ((unsigned int) 0x20000000) +#define SCB_PIOPORCAP0_PIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_PIOPORCAP0_PIO2_6 ((unsigned int) 0x40000000) +#define SCB_PIOPORCAP0_PIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_PIOPORCAP0_PIO2_7 ((unsigned int) 0x80000000) +#define SCB_PIOPORCAP0_PIO2_7_MASK ((unsigned int) 0x80000000) + +/* PIOPORCAP1 (POR captured PIO status register 1) + The PIOPORCAP1 register captures the state (HIGH or LOW) of the PIO pins of port 2 + (PIO2_8 to PIO2_11) and port 3 at power-on-reset. Each bit represents the reset state of + one PIO pin. This register is a read-only status register. */ + +#define SCB_PIOPORCAP1_PIO2_8 ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP1_PIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP1_PIO2_9 ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP1_PIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP1_PIO2_10 ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP1_PIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP1_PIO2_11 ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP1_PIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP1_PIO3_0 ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP1_PIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP1_PIO3_1 ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP1_PIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP1_PIO3_2 ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP1_PIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP1_PIO3_3 ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP1_PIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP1_PIO3_4 ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP1_PIO3_4_MASK ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP1_PIO3_5 ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP1_PIO3_5_MASK ((unsigned int) 0x00000200) + +/* BODCTRL (Brown-out detection control register) + The BOD control register selects four separate threshold values for sending a BOD + interrupt to the NVIC. Only one level is allowed for forced reset. */ + +#define SCB_BODCTRL_RSTLEVEL_MASK ((unsigned int) 0x00000003) +#define SCB_BODCTRL_INTLEVEL_1_69V_1_84V ((unsigned int) 0x00000000) +#define SCB_BODCTRL_INTLEVEL_2_29V_2_44V ((unsigned int) 0x00000004) +#define SCB_BODCTRL_INTLEVEL_2_59V_2_74V ((unsigned int) 0x00000008) +#define SCB_BODCTRL_INTLEVEL_2_87V_2_98V ((unsigned int) 0x0000000C) +#define SCB_BODCTRL_INTLEVEL_MASK ((unsigned int) 0x0000000C) +#define SCB_BODCTRL_RSTENABLE_DISABLE ((unsigned int) 0x00000000) +#define SCB_BODCTRL_RSTENABLE_ENABLE ((unsigned int) 0x00000010) +#define SCB_BODCTRL_RSTENABLE_MASK ((unsigned int) 0x00000010) + +/* SYSTCKCAL (System tick counter calibration register) */ + +#define SCB_SYSTICKCCAL_MASK ((unsigned int) 0x03FFFFFF) // Undefined as of v0.07 of the LPC1343 User Manual + +/* STARTAPRP0 (Start logic edge control register 0) + The STARTAPRP0 register controls the start logic inputs of ports 0 (PIO0_0 to PIO0_11) + and 1 (PIO1_0 to PIO1_11) and the lower 8 inputs of port 2 (PIO2_0 to PIO2_7). This + register selects a falling or rising edge on the corresponding PIO input to produce a falling + or rising clock edge, respectively, for the start logic (see Section 3–9.3). + Every bit in the STARTAPRP0 register controls one port input and is connected to one + wake-up interrupt in the NVIC. Bit 0 in the STARTAPRP0 register corresponds to interrupt + 0, bit 1 to interrupt 1, etc.. The bottom 32 interrupts are contained this register, + the top 8 interrupts are contained in the STARTAPRP1 register for total of 40 wake-up + interrupts. + Remark: Each interrupt connected to a start logic input must be enabled in the NVIC if the + corresponding PIO pin is used to wake up the chip from Deep-sleep mode. */ + +#define SCB_STARTAPRP0_APRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP0_APRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTAPRP0_APRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTAPRP0_APRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTAPRP0_APRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTAPRP0_APRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTAPRP0_APRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTAPRP0_APRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTAPRP0_APRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTAPRP0_APRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTAPRP0_APRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTAPRP0_APRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTAPRP0_APRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTAPRP0_APRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTAPRP0_APRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTAPRP0_APRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTAPRP0_APRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTAPRP0_APRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTAPRP0_APRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTAPRP0_APRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTAPRP0_APRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTAPRP0_APRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTAPRP0_APRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTAPRP0_APRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTAPRP0_APRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTAPRP0_APRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTAPRP0_APRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTAPRP0_APRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTAPRP0_APRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTAPRP0_APRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTAPRP0_APRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTAPRP0_APRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTAPRP0_APRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTAPRP0_APRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTAPRP0_APRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTAPRP0_APRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTAPRP0_APRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTAPRP0_APRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTAPRP0_APRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTAPRP0_APRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTAPRP0_APRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTAPRP0_APRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTAPRP0_APRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTAPRP0_APRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTAPRP0_APRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTAPRP0_APRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTAPRP0_APRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTAPRP0_APRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTAPRP0_APRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTAPRP0_APRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTAPRP0_APRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTAPRP0_APRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTAPRP0_APRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTAPRP0_APRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTAPRP0_APRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTAPRP0_APRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTAPRP0_APRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTAPRP0_APRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTAPRP0_APRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTAPRP0_APRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTAPRP0_APRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTAPRP0_APRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTAPRP0_APRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTAPRP0_APRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTAPRP0_MASK ((unsigned int) 0xFFFFFFFF) + +/* STARTERP0 (Start logic signal enable register 0) + This STARTERP0 register enables or disables the start signal bits in the start logic. */ + +#define SCB_STARTERP0_ERPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTERP0_ERPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTERP0_ERPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTERP0_ERPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTERP0_ERPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTERP0_ERPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTERP0_ERPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTERP0_ERPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTERP0_ERPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTERP0_ERPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTERP0_ERPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTERP0_ERPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTERP0_ERPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTERP0_ERPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTERP0_ERPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTERP0_ERPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTERP0_ERPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTERP0_ERPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTERP0_ERPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTERP0_ERPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTERP0_ERPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTERP0_ERPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTERP0_ERPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTERP0_ERPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTERP0_ERPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTERP0_ERPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTERP0_ERPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTERP0_ERPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTERP0_ERPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTERP0_ERPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTERP0_ERPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTERP0_ERPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTERP0_ERPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTERP0_ERPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTERP0_ERPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTERP0_ERPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTERP0_ERPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTERP0_ERPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTERP0_ERPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTERP0_ERPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTERP0_ERPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTERP0_ERPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTERP0_ERPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTERP0_ERPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTERP0_ERPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTERP0_ERPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTERP0_ERPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTERP0_ERPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTERP0_ERPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTERP0_ERPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTERP0_ERPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTERP0_ERPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTERP0_ERPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTERP0_ERPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTERP0_ERPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTERP0_ERPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTERP0_ERPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTERP0_ERPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTERP0_ERPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTERP0_ERPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTERP0_ERPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTERP0_ERPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTERP0_ERPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTERP0_ERPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTERP0_MASK ((unsigned int) 0xFFFFFFFF) + +/* STARTRSRP0CLR (Start logic reset register 0) + Writing a one to a bit in the STARTRSRP0CLR register resets the start logic state. The + start-up logic uses the input signals to generate a clock edge for registering a start + signal. This clock edge (falling or rising) sets the interrupt for waking up from + Deep-sleep mode. Therefore, the start-up logic states must be cleared before being used. */ + +#define SCB_STARTRSRP0CLR_RSRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP0CLR_RSRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTRSRP0CLR_RSRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTRSRP0CLR_RSRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTRSRP0CLR_RSRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTRSRP0CLR_RSRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTRSRP0CLR_RSRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTRSRP0CLR_RSRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTRSRP0CLR_RSRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTRSRP0CLR_RSRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTRSRP0CLR_RSRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTRSRP0CLR_RSRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTRSRP0CLR_RSRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTRSRP0CLR_RSRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTRSRP0CLR_RSRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTRSRP0CLR_RSRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTRSRP0CLR_RSRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTRSRP0CLR_RSRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTRSRP0CLR_RSRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTRSRP0CLR_RSRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTRSRP0CLR_RSRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTRSRP0CLR_RSRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTRSRP0CLR_RSRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTRSRP0CLR_RSRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTRSRP0CLR_RSRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTRSRP0CLR_RSRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTRSRP0CLR_RSRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTRSRP0CLR_RSRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTRSRP0CLR_RSRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTRSRP0CLR_RSRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTRSRP0CLR_RSRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTRSRP0CLR_RSRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTRSRP0CLR_RSRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTRSRP0CLR_RSRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTRSRP0CLR_RSRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTRSRP0CLR_RSRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTRSRP0CLR_RSRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTRSRP0CLR_RSRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTRSRP0CLR_RSRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTRSRP0CLR_RSRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTRSRP0CLR_RSRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTRSRP0CLR_RSRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTRSRP0CLR_RSRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTRSRP0CLR_RSRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTRSRP0CLR_RSRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTRSRP0CLR_RSRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTRSRP0CLR_RSRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTRSRP0CLR_RSRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTRSRP0CLR_RSRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTRSRP0CLR_MASK ((unsigned int) 0xFFFFFFFF) + +/* (Start logic status register 0) + This register reflects the status of the enabled start signal bits. Each bit + (if enabled) reflects the state of the start logic, i.e. whether or not a + wake-up signal has been received for a given pin. */ + +#define SCB_STARTSRP0_SRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTSRP0_SRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTSRP0_SRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTSRP0_SRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTSRP0_SRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTSRP0_SRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTSRP0_SRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTSRP0_SRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTSRP0_SRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTSRP0_SRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTSRP0_SRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTSRP0_SRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTSRP0_SRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTSRP0_SRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTSRP0_SRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTSRP0_SRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTSRP0_SRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTSRP0_SRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTSRP0_SRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTSRP0_SRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTSRP0_SRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTSRP0_SRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTSRP0_SRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTSRP0_SRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTSRP0_SRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTSRP0_SRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTSRP0_SRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTSRP0_SRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTSRP0_SRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTSRP0_SRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTSRP0_SRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTSRP0_SRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTSRP0_SRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTSRP0_SRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTSRP0_SRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTSRP0_SRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTSRP0_SRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTSRP0_SRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTSRP0_SRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTSRP0_SRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTSRP0_SRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTSRP0_SRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTSRP0_SRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTSRP0_SRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTSRP0_SRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTSRP0_SRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTSRP0_SRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTSRP0_SRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTSRP0_SRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTSRP0_SRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTSRP0_SRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTSRP0_SRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTSRP0_SRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTSRP0_SRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTSRP0_SRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTSRP0_SRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTSRP0_SRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTSRP0_SRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTSRP0_SRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTSRP0_SRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTSRP0_SRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTSRP0_SRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTSRP0_SRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTSRP0_SRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTSRP0_MASK ((unsigned int) 0xFFFFFFFF) + + +/* STARTAPRP1 (Start logic edge control register 1) + The STARTAPRP1 register controls the start logic inputs of ports 2 (PIO2_8 to PIO2_11) + and 3 (PIO3_0 to PIO3_3). This register selects a falling or rising edge on the + corresponding PIO input to produce a falling or rising clock edge, respectively, for the + start-up logic. + Every bit in the STARTAPRP1 register controls one port input and is connected to one + wake-up interrupt in the NVIC. Bit 0 in the STARTAPRP1 register corresponds to interrupt + 32, bit 1 to interrupt 33, up to bit 7 corresponding to interrupt 39. + Remark: Each interrupt connected to a start logic input must be enabled in the NVIC if the + corresponding PIO pin is used to wake up the chip from Deep-sleep mode.*/ + +#define SCB_STARTAPRP1_APRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTAPRP1_APRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTAPRP1_APRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTAPRP1_APRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTAPRP1_APRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTAPRP1_APRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTAPRP1_APRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTAPRP1_APRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTAPRP1_APRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTAPRP1_APRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTAPRP1_APRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTAPRP1_APRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTAPRP1_APRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTAPRP1_MASK ((unsigned int) 0x000000FF) + +/* STARTERP1 (Start logic signal enable register 1) + This STARTERP1 register enables or disables the start signal bits in the start logic. */ + +#define SCB_STARTERP1_ERPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTERP1_ERPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTERP1_ERPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTERP1_ERPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTERP1_ERPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTERP1_ERPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTERP1_ERPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTERP1_ERPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTERP1_ERPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTERP1_ERPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTERP1_ERPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTERP1_ERPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTERP1_ERPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTERP1_MASK ((unsigned int) 0x000000FF) + +/* (Start logic reset register 1) + Writing a one to a bit in the STARTRSRP1CLR register resets the start logic state. The + start-up logic uses the input signals to generate a clock edge for registering a start + signal. This clock edge (falling or rising) sets the interrupt for waking up from + Deep-sleep mode. Therefore, the start-up logic states must be cleared before being used. */ + +#define SCB_STARTRSRP1CLR_RSRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTRSRP1CLR_RSRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTRSRP1CLR_RSRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTRSRP1CLR_RSRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTRSRP1CLR_RSRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTRSRP1CLR_RSRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTRSRP1CLR_RSRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTRSRP1CLR_RSRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTRSRP1CLR_RSRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTRSRP1CLR_RSRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTRSRP1CLR_RSRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTRSRP1CLR_RSRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTRSRP1CLR_RSRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTRSRP1CLR_MASK ((unsigned int) 0x000000FF) + +/* STARTSRP1 (Start logic status register 1) + This register reflects the status of the enabled start signals. */ + +#define SCB_STARTSRP1_SRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTSRP1_SRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTSRP1_SRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTSRP1_SRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTSRP1_SRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTSRP1_SRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTSRP1_SRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTSRP1_SRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTSRP1_SRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTSRP1_SRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTSRP1_SRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTSRP1_SRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTSRP1_SRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTSRP1_MASK ((unsigned int) 0x000000FF) + +/* PDSLEEPCFG (Deep-sleep mode configuration register) + The bits in this register can be programmed to indicate the state the chip must enter when + the Deep-sleep mode is asserted by the ARM. The value of the PDSLEEPCFG register + will be automatically loaded into the PDRUNCFG register when the Sleep mode is + entered. */ + +#define SCB_PDSLEEPCFG_IRCOUT_PD ((unsigned int) 0x00000001) +#define SCB_PDSLEEPCFG_IRCOUT_PD_MASK ((unsigned int) 0x00000001) +#define SCB_PDSLEEPCFG_IRC_PD ((unsigned int) 0x00000002) +#define SCB_PDSLEEPCFG_IRC_PD_MASK ((unsigned int) 0x00000002) +#define SCB_PDSLEEPCFG_FLASH_PD ((unsigned int) 0x00000004) +#define SCB_PDSLEEPCFG_FLASH_PD_MASK ((unsigned int) 0x00000004) +#define SCB_PDSLEEPCFG_BOD_PD ((unsigned int) 0x00000008) +#define SCB_PDSLEEPCFG_BOD_PD_MASK ((unsigned int) 0x00000008) +#define SCB_PDSLEEPCFG_ADC_PD ((unsigned int) 0x00000010) +#define SCB_PDSLEEPCFG_ADC_PD_MASK ((unsigned int) 0x00000010) +#define SCB_PDSLEEPCFG_SYSOSC_PD ((unsigned int) 0x00000020) +#define SCB_PDSLEEPCFG_SYSOSC_PD_MASK ((unsigned int) 0x00000020) +#define SCB_PDSLEEPCFG_WDTOSC_PD ((unsigned int) 0x00000040) +#define SCB_PDSLEEPCFG_WDTOSC_PD_MASK ((unsigned int) 0x00000040) +#define SCB_PDSLEEPCFG_SYSPLL_PD ((unsigned int) 0x00000080) +#define SCB_PDSLEEPCFG_SYSPLL_PD_MASK ((unsigned int) 0x00000080) +#define SCB_PDSLEEPCFG_USBPLL_PD ((unsigned int) 0x00000100) +#define SCB_PDSLEEPCFG_USBPLL_PD_MASK ((unsigned int) 0x00000100) +#define SCB_PDSLEEPCFG_USBPAD_PD ((unsigned int) 0x00000400) +#define SCB_PDSLEEPCFG_USBPAD_PD_MASK ((unsigned int) 0x00000400) + +/* PDAWAKECFG (Wake-up configuration register) + The bits in this register can be programmed to indicate the state the chip must enter when + it is waking up from Deep-sleep mode. */ + +#define SCB_PDAWAKECFG_IRCOUT_PD ((unsigned int) 0x00000001) +#define SCB_PDAWAKECFG_IRCOUT_PD_MASK ((unsigned int) 0x00000001) +#define SCB_PDAWAKECFG_IRC_PD ((unsigned int) 0x00000002) +#define SCB_PDAWAKECFG_IRC_PD_MASK ((unsigned int) 0x00000002) +#define SCB_PDAWAKECFG_FLASH_PD ((unsigned int) 0x00000004) +#define SCB_PDAWAKECFG_FLASH_PD_MASK ((unsigned int) 0x00000004) +#define SCB_PDAWAKECFG_BOD_PD ((unsigned int) 0x00000008) +#define SCB_PDAWAKECFG_BOD_PD_MASK ((unsigned int) 0x00000008) +#define SCB_PDAWAKECFG_ADC_PD ((unsigned int) 0x00000010) +#define SCB_PDAWAKECFG_ADC_PD_MASK ((unsigned int) 0x00000010) +#define SCB_PDAWAKECFG_SYSOSC_PD ((unsigned int) 0x00000020) +#define SCB_PDAWAKECFG_SYSOSC_PD_MASK ((unsigned int) 0x00000020) +#define SCB_PDAWAKECFG_WDTOSC_PD ((unsigned int) 0x00000040) +#define SCB_PDAWAKECFG_WDTOSC_PD_MASK ((unsigned int) 0x00000040) +#define SCB_PDAWAKECFG_SYSPLL_PD ((unsigned int) 0x00000080) +#define SCB_PDAWAKECFG_SYSPLL_PD_MASK ((unsigned int) 0x00000080) +#define SCB_PDAWAKECFG_USBPLL_PD ((unsigned int) 0x00000100) +#define SCB_PDAWAKECFG_USBPLL_PD_MASK ((unsigned int) 0x00000100) +#define SCB_PDAWAKECFG_USBPAD_PD ((unsigned int) 0x00000400) +#define SCB_PDAWAKECFG_USBPAD_PD_MASK ((unsigned int) 0x00000400) + +/* PDRUNCFG (Power-down configuration register) + The bits in the PDRUNCFG register control the power to the various analog blocks. This + register can be written to at any time while the chip is running, and a write will take effect + immediately with the exception of the power-down signal to the IRC. Setting a 1 powers-down + a peripheral and 0 enables it. */ + +#define SCB_PDRUNCFG_IRCOUT ((unsigned int) 0x00000001) // IRC oscillator output power-down +#define SCB_PDRUNCFG_IRCOUT_MASK ((unsigned int) 0x00000001) +#define SCB_PDRUNCFG_IRC ((unsigned int) 0x00000002) // IRC oscillator power-down +#define SCB_PDRUNCFG_IRC_MASK ((unsigned int) 0x00000002) +#define SCB_PDRUNCFG_FLASH ((unsigned int) 0x00000004) // Flash power-down +#define SCB_PDRUNCFG_FLASH_MASK ((unsigned int) 0x00000004) +#define SCB_PDRUNCFG_BOD ((unsigned int) 0x00000008) // Brown-out detector power-down +#define SCB_PDRUNCFG_BOD_MASK ((unsigned int) 0x00000008) +#define SCB_PDRUNCFG_ADC ((unsigned int) 0x00000010) // ADC power-down +#define SCB_PDRUNCFG_ADC_MASK ((unsigned int) 0x00000010) +#define SCB_PDRUNCFG_SYSOSC ((unsigned int) 0x00000020) // System oscillator power-down +#define SCB_PDRUNCFG_SYSOSC_MASK ((unsigned int) 0x00000020) +#define SCB_PDRUNCFG_WDTOSC ((unsigned int) 0x00000040) // Watchdog oscillator power-down +#define SCB_PDRUNCFG_WDTOSC_MASK ((unsigned int) 0x00000040) +#define SCB_PDRUNCFG_SYSPLL ((unsigned int) 0x00000080) // System PLL power-down +#define SCB_PDRUNCFG_SYSPLL_MASK ((unsigned int) 0x00000080) +#define SCB_PDRUNCFG_USBPLL ((unsigned int) 0x00000100) // USB PLL power-down +#define SCB_PDRUNCFG_USBPLL_MASK ((unsigned int) 0x00000100) +#define SCB_PDRUNCFG_USBPAD ((unsigned int) 0x00000400) // USB PHY power-down +#define SCB_PDRUNCFG_USBPAD_MASK ((unsigned int) 0x00000400) + +/* DEVICE_ID (Device ID Register) + This device ID register is a read-only register and contains the device ID for each + LPC13xx part. This register is also read by the ISP/IAP commands. */ + +#define SCB_DEVICEID_LPC1311FHN33 ((unsigned int) 0x2C42502B) +#define SCB_DEVICEID_LPC1313FHN33 ((unsigned int) 0x2C40102B) +#define SCB_DEVICEID_LPC1313FBD48 ((unsigned int) 0x2C40102B) +#define SCB_DEVICEID_LPC1342FHN33 ((unsigned int) 0x3D01402B) +#define SCB_DEVICEID_LPC1343FHN33 ((unsigned int) 0x3D00002B) +#define SCB_DEVICEID_LPC1343FBD48 ((unsigned int) 0x3D00002B) + +/*############################################################################## +## Data Watchpoint and Trace Unit (DWT) +##############################################################################*/ +// For more information, see Cortex-M3 Technical Reference Manual 8.3 +// This block is optional and not all comparators or functionality may +// be present on all chips, though basic DWT functionality is present +// on the LPC1343 since CYCNT works + +#define DWT_CTRL (*(pREG32 (0xE0001000))) // Control register +#define DWT_CYCCNT (*(pREG32 (0xE0001004))) // Cycle counter (useful for rough performance testing) +#define DWT_CPICNT (*(pREG32 (0xE0001008))) // CPI Count Register +#define DWT_EXCCNT (*(pREG32 (0xE000100C))) // Exception overhead count register +#define DWT_SLEEPCNT (*(pREG32 (0xE0001010))) // Sleep count register +#define DWT_LSUCNT (*(pREG32 (0xE0001014))) // LSU count register +#define DWT_FOLDCNT (*(pREG32 (0xE0001018))) // Folder-instruction count register +#define DWT_PCSR (*(pREG32 (0xE000101C))) // Program counter sample register +#define DWT_COMP0 (*(pREG32 (0xE0001020))) // Comparator register 0 +#define DWT_MASK0 (*(pREG32 (0xE0001024))) // Mask register 0 +#define DWT_FUNCTION0 (*(pREG32 (0xE0001028))) // Function register 0 +#define DWT_COMP1 (*(pREG32 (0xE0001030))) // Comparator register 1 +#define DWT_MASK1 (*(pREG32 (0xE0001034))) // Mask register 1 +#define DWT_FUNCTION1 (*(pREG32 (0xE0001038))) // Function register 1 +#define DWT_COMP2 (*(pREG32 (0xE0001040))) // Comparator register 2 +#define DWT_MASK2 (*(pREG32 (0xE0001044))) // Mask register 2 +#define DWT_FUNCTION2 (*(pREG32 (0xE0001048))) // Function register 2 +#define DWT_COMP3 (*(pREG32 (0xE0001050))) // Comparator register 3 +#define DWT_MASK3 (*(pREG32 (0xE0001054))) // Mask register 3 +#define DWT_FUNCTION3 (*(pREG32 (0xE0001058))) // Function register 3 + +/*############################################################################## +## Power Management Unit (PMU) +##############################################################################*/ + +#define PMU_BASE_ADDRESS (0x40038000) + +#define PMU_PMUCTRL (*(pREG32 (0x40038000))) // Power control register +#define PMU_GPREG0 (*(pREG32 (0x40038004))) // General purpose register 0 +#define PMU_GPREG1 (*(pREG32 (0x40038008))) // General purpose register 1 +#define PMU_GPREG2 (*(pREG32 (0x4003800C))) // General purpose register 2 +#define PMU_GPREG3 (*(pREG32 (0x40038010))) // General purpose register 3 +#define PMU_GPREG4 (*(pREG32 (0x40038014))) // General purpose register 4 + +#define PMU_PMUCTRL_DPDEN_MASK ((unsigned int) 0x00000002) // Deep power-down enable +#define PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN ((unsigned int) 0x00000002) // WFI will enter deep power-down mode +#define PMU_PMUCTRL_DPDEN_SLEEP ((unsigned int) 0x00000000) // WFI will enter sleep mode +#define PMU_PMUCTRL_DPDFLAG_MASK ((unsigned int) 0x00000800) // Deep power-down flag +#define PMU_PMUCTRL_DPDFLAG ((unsigned int) 0x00000800) + +/* GPREG0..3 (General purpose registers 0 to 3) + The general purpose registers retain data through the Deep power-down mode when + power is still applied to the VDD(3V3) pin but the chip has entered Deep power-down mode. + Only a “cold” boot when all power has been completely removed from the chip will reset + the general purpose registers. */ + +#define PMU_GPREG0_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG1_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG2_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG3_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) + +/* GPREG4 (General purpose register 4) + The general purpose register 4 retains data through the Deep power-down mode when + power is still applied to the VDD(3V3) pin but the chip has entered Deep power-down mode. + Only a “cold” boot, when all power has been completely removed from the chip, will reset + the general purpose registers. + + Remark: If the external voltage applied on pin VDD(3V3) drops below V, the + hysteresis of the WAKEUP input pin has to be disabled in order for the chip to wake up + from Deep power-down mode. */ + +#define PMU_GPREG4_GPDATA_MASK ((unsigned int) 0xFFFFF800) +#define PMU_GPREG4_WAKEUPHYS_MASK ((unsigned int) 0x00000400) +#define PMU_GPREG4_WAKEUPHYS_HYSTERESISENABLED ((unsigned int) 0x00000400) +#define PMU_GPREG4_WAKEUPHYS_HYSTERESISDISABLED ((unsigned int) 0x00000000) +#define PMU_GPREG4_GPDATA_MASK ((unsigned int) 0xFFFFF800) + +/*############################################################################## +## I/O Control (IOCON) +##############################################################################*/ + +#define IOCON_BASE_ADDRESS (0x40044000) + +/* Values that should be common to all pins, though they are also defined + on the individual pin level in case they change with a pin on any future + device */ + +#define IOCON_COMMON_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_COMMON_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_COMMON_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_COMMON_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_COMMON_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_COMMON_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_COMMON_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_COMMON_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_COMMON_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_6 (*(pREG32 (0x40044000))) +#define IOCON_PIO2_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_0 (*(pREG32 (0x40044008))) +#define IOCON_PIO2_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_0_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_FUNC_DTR ((unsigned int) 0x00000001) +#define IOCON_PIO2_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_nRESET_PIO0_0 (*(pREG32 (0x4004400C))) +#define IOCON_nRESET_PIO0_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_nRESET_PIO0_0_FUNC_RESET ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_nRESET_PIO0_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_nRESET_PIO0_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_nRESET_PIO0_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_nRESET_PIO0_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_nRESET_PIO0_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_nRESET_PIO0_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_1 (*(pREG32 (0x40044010))) +#define IOCON_PIO0_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_FUNC_CLKOUT ((unsigned int) 0x00000001) +#define IOCON_PIO0_1_FUNC_CT32B0_MAT2 ((unsigned int) 0x00000002) +#define IOCON_PIO0_1_FUNC_USB_FTOGGLE ((unsigned int) 0x00000003) +#define IOCON_PIO0_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_8 (*(pREG32 (0x40044014))) +#define IOCON_PIO1_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_FUNC_CT16B1_CAP0 ((unsigned int) 0x00000001) +#define IOCON_PIO1_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_2 (*(pREG32 (0x4004401C))) +#define IOCON_PIO0_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_FUNC_SSEL ((unsigned int) 0x00000001) +#define IOCON_PIO0_2_FUNC_CT16B0_CAP0 ((unsigned int) 0x00000002) +#define IOCON_PIO0_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_7 (*(pREG32 (0x40044020))) +#define IOCON_PIO2_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_8 (*(pREG32 (0x40044024))) +#define IOCON_PIO2_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_1 (*(pREG32 (0x40044028))) +#define IOCON_PIO2_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_FUNC_DSR ((unsigned int) 0x00000001) +#define IOCON_PIO2_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_3 (*(pREG32 (0x4004402C))) +#define IOCON_PIO0_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_3_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_FUNC_USB_VBUS ((unsigned int) 0x00000001) +#define IOCON_PIO0_3_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_3_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_3_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_3_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_4 (*(pREG32 (0x40044030))) +#define IOCON_PIO0_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_4_FUNC_I2CSCL ((unsigned int) 0x00000001) +#define IOCON_PIO0_4_I2CMODE_MASK ((unsigned int) 0x00000300) +#define IOCON_PIO0_4_I2CMODE_STANDARDI2C ((unsigned int) 0x00000000) +#define IOCON_PIO0_4_I2CMODE_STANDARDIO ((unsigned int) 0x00000100) +#define IOCON_PIO0_4_I2CMODE_FASTPLUSI2C ((unsigned int) 0x00000200) + +#define IOCON_PIO0_5 (*(pREG32 (0x40044034))) +#define IOCON_PIO0_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_5_FUNC_I2CSDA ((unsigned int) 0x00000001) +#define IOCON_PIO0_5_I2CMODE_MASK ((unsigned int) 0x00000300) +#define IOCON_PIO0_5_I2CMODE_STANDARDI2C ((unsigned int) 0x00000000) +#define IOCON_PIO0_5_I2CMODE_STANDARDIO ((unsigned int) 0x00000100) +#define IOCON_PIO0_5_I2CMODE_FASTPLUSI2C ((unsigned int) 0x00000200) + +#define IOCON_PIO1_9 (*(pREG32 (0x40044038))) +#define IOCON_PIO1_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_FUNC_CT16B1_MAT0 ((unsigned int) 0x00000001) +#define IOCON_PIO1_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_4 (*(pREG32 (0x4004403C))) +#define IOCON_PIO3_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_4 (*(pREG32 (0x40044040))) +#define IOCON_PIO2_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_5 (*(pREG32 (0x40044044))) +#define IOCON_PIO2_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_5 (*(pREG32 (0x40044048))) +#define IOCON_PIO3_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_6 (*(pREG32 (0x4004404C))) +#define IOCON_PIO0_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_FUNC_USB_CONNECT ((unsigned int) 0x00000001) +#define IOCON_PIO0_6_FUNC_SCK ((unsigned int) 0x00000002) +#define IOCON_PIO0_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_HYS_ENABLE ((unsigned int) 0x00000020) + + +#define IOCON_PIO0_7 (*(pREG32 (0x40044050))) +#define IOCON_PIO0_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_FUNC_CTS ((unsigned int) 0x00000001) +#define IOCON_PIO0_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_9 (*(pREG32 (0x40044054))) +#define IOCON_PIO2_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_10 (*(pREG32 (0x40044058))) +#define IOCON_PIO2_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_10_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_2 (*(pREG32 (0x4004405C))) +#define IOCON_PIO2_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_FUNC_DCD ((unsigned int) 0x00000001) +#define IOCON_PIO2_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_8 (*(pREG32 (0x40044060))) +#define IOCON_PIO0_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_FUNC_MISO0 ((unsigned int) 0x00000001) +#define IOCON_PIO0_8_FUNC_CT16B0_MAT0 ((unsigned int) 0x00000002) +#define IOCON_PIO0_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_9 (*(pREG32 (0x40044064))) +#define IOCON_PIO0_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_FUNC_MOSI0 ((unsigned int) 0x00000001) +#define IOCON_PIO0_9_FUNC_CT16B0_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO0_9_FUNC_SWO ((unsigned int) 0x00000003) +#define IOCON_PIO0_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_JTAG_TCK_PIO0_10 (*(pREG32 (0x40044068))) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_SWCLK ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_SCK ((unsigned int) 0x00000002) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_CT16B0_MAT2 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TCK_PIO0_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TCK_PIO0_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TCK_PIO0_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TCK_PIO0_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TCK_PIO0_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TCK_PIO0_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_10 (*(pREG32 (0x4004406C))) +#define IOCON_PIO1_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_10_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_FUNC_AD6 ((unsigned int) 0x00000001) +#define IOCON_PIO1_10_FUNC_CT16B1_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO1_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_10_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_10_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO2_11 (*(pREG32 (0x40044070))) +#define IOCON_PIO2_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_11_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_FUNC_SCK0 ((unsigned int) 0x00000001) +#define IOCON_PIO2_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_JTAG_TDI_PIO0_11 (*(pREG32 (0x40044074))) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_TDI ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_AD0 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_CT32B0_MAT3 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TDI_PIO0_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDI_PIO0_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TDI_PIO0_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TDI_PIO0_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDI_PIO0_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDI_PIO0_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_TMS_PIO1_0 (*(pREG32 (0x40044078))) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_TMS ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_AD1 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_CT32B1_CAP0 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TMS_PIO1_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TMS_PIO1_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TMS_PIO1_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TMS_PIO1_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TMS_PIO1_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TMS_PIO1_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_TDO_PIO1_1 (*(pREG32 (0x4004407C))) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_TDO ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_AD2 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_CT32B1_MAT0 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TDO_PIO1_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDO_PIO1_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TDO_PIO1_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TDO_PIO1_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDO_PIO1_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDO_PIO1_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_nTRST_PIO1_2 (*(pREG32 (0x40044080))) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_TRST ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3 ((unsigned int) 0x00000002) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_CT32B1_MAT1 ((unsigned int) 0x00000003) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO3_0 (*(pREG32 (0x40044084))) +#define IOCON_PIO3_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_0_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_1 (*(pREG32 (0x40044088))) +#define IOCON_PIO3_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_3 (*(pREG32 (0x4004408C))) +#define IOCON_PIO2_3_FUNC_MASK 0x7 +#define IOCON_PIO2_3_MODE_MASK 0x18 +#define IOCON_PIO2_3_HYS_MASK 0x20 +#define IOCON_PIO2_3_HYS 0x20 + +#define IOCON_SWDIO_PIO1_3 (*(pREG32 (0x40044090))) +#define IOCON_SWDIO_PIO1_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_SWDIO_PIO1_3_FUNC_SWDIO ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_SWDIO_PIO1_3_FUNC_AD4 ((unsigned int) 0x00000002) +#define IOCON_SWDIO_PIO1_3_FUNC_CT32B1_MAT2 ((unsigned int) 0x00000004) +#define IOCON_SWDIO_PIO1_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_SWDIO_PIO1_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_SWDIO_PIO1_3_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_SWDIO_PIO1_3_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO1_4 (*(pREG32 (0x40044094))) +#define IOCON_PIO1_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_FUNC_AD5 ((unsigned int) 0x00000001) +#define IOCON_PIO1_4_FUNC_CT32B1_MAT3 ((unsigned int) 0x00000002) +#define IOCON_PIO1_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_4_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_4_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO1_11 (*(pREG32 (0x40044098))) +#define IOCON_PIO1_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_11_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_FUNC_AD7 ((unsigned int) 0x00000001) +#define IOCON_PIO1_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_11_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_11_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO3_2 (*(pREG32 (0x4004409C))) +#define IOCON_PIO3_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_5 (*(pREG32 (0x400440A0))) +#define IOCON_PIO1_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_FUNC_RTS ((unsigned int) 0x00000001) +#define IOCON_PIO1_5_FUNC_CT32B0_CAP0 ((unsigned int) 0x00000002) +#define IOCON_PIO1_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_6 (*(pREG32 (0x400440A4))) +#define IOCON_PIO1_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_FUNC_UART_RXD ((unsigned int) 0x00000001) +#define IOCON_PIO1_6_FUNC_CT32B0_MAT0 ((unsigned int) 0x00000002) +#define IOCON_PIO1_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_7 (*(pREG32 (0x400440A8))) +#define IOCON_PIO1_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_FUNC_UART_TXD ((unsigned int) 0x00000001) +#define IOCON_PIO1_7_FUNC_CT32B0_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO1_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_3 (*(pREG32 (0x400440AC))) +#define IOCON_PIO3_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_3_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_3_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_3_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_3_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_SCKLOC (*(pREG32 (0x400440B0))) +#define IOCON_SCKLOC_SCKPIN_MASK ((unsigned int) 0x00000003) +#define IOCON_SCKLOC_SCKPIN_PIO0_10 ((unsigned int) 0x00000000) // Set SCK function to pin 0.10 +#define IOCON_SCKLOC_SCKPIN_PIO2_11 ((unsigned int) 0x00000001) // Set SCK function to pin 2.11 +#define IOCON_SCKLOC_SCKPIN_PIO0_6 ((unsigned int) 0x00000003) // Set SCK function to pin 0.6 + +#define IOCON_SWCLK_PIO0_10 (*(pREG32 (0x40044068))) + +/*############################################################################## +## Nested Vectored Interrupt Controller +##############################################################################*/ + +#define NVIC_BASE_ADDRESS (0xE000E100) + +typedef struct +{ + volatile uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + volatile uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + volatile uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + volatile uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + volatile uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + volatile uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + volatile uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ +} NVIC_Type; + +#define NVIC ((NVIC_Type *) NVIC_BASE_ADDRESS) + +static inline void __enable_irq() { __asm volatile ("cpsie i"); } +static inline void __disable_irq() { __asm volatile ("cpsid i"); } + +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC13xx Specific Interrupt Numbers *******************************************************/ + WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */ + WAKEUP1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */ + WAKEUP2_IRQn = 2, + WAKEUP3_IRQn = 3, + WAKEUP4_IRQn = 4, + WAKEUP5_IRQn = 5, + WAKEUP6_IRQn = 6, + WAKEUP7_IRQn = 7, + WAKEUP8_IRQn = 8, + WAKEUP9_IRQn = 9, + WAKEUP10_IRQn = 10, + WAKEUP11_IRQn = 11, + WAKEUP12_IRQn = 12, + WAKEUP13_IRQn = 13, + WAKEUP14_IRQn = 14, + WAKEUP15_IRQn = 15, + WAKEUP16_IRQn = 16, + WAKEUP17_IRQn = 17, + WAKEUP18_IRQn = 18, + WAKEUP19_IRQn = 19, + WAKEUP20_IRQn = 20, + WAKEUP21_IRQn = 21, + WAKEUP22_IRQn = 22, + WAKEUP23_IRQn = 23, + WAKEUP24_IRQn = 24, + WAKEUP25_IRQn = 25, + WAKEUP26_IRQn = 26, + WAKEUP27_IRQn = 27, + WAKEUP28_IRQn = 28, + WAKEUP29_IRQn = 29, + WAKEUP30_IRQn = 30, + WAKEUP31_IRQn = 31, + WAKEUP32_IRQn = 32, + WAKEUP33_IRQn = 33, + WAKEUP34_IRQn = 34, + WAKEUP35_IRQn = 35, + WAKEUP36_IRQn = 36, + WAKEUP37_IRQn = 37, + WAKEUP38_IRQn = 38, + WAKEUP39_IRQn = 39, + I2C_IRQn = 40, /*!< I2C Interrupt */ + TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */ + TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */ + TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */ + TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */ + SSP_IRQn = 45, /*!< SSP Interrupt */ + UART_IRQn = 46, /*!< UART Interrupt */ + USB_IRQn = 47, /*!< USB Regular Interrupt */ + USB_FIQn = 48, /*!< USB Fast Interrupt */ + ADC_IRQn = 49, /*!< A/D Converter Interrupt */ + WDT_IRQn = 50, /*!< Watchdog timer Interrupt */ + BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */ + EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */ + EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */ + EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */ + EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */ +} IRQn_t; + +static inline void NVIC_EnableIRQ(IRQn_t IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +static inline void NVIC_DisableIRQ(IRQn_t IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/*############################################################################## +## GPIO - General Purpose I/O +##############################################################################*/ + +#define GPIO_GPIO0_BASE (0x50000000) +#define GPIO_GPIO1_BASE (0x50010000) +#define GPIO_GPIO2_BASE (0x50020000) +#define GPIO_GPIO3_BASE (0x50030000) + +#define GPIO_GPIO0DATA (*(pREG32 (0x50003FFC))) // Port data register +#define GPIO_GPIO0DIR (*(pREG32 (0x50008000))) // Data direction register +#define GPIO_GPIO0IS (*(pREG32 (0x50008004))) // Interrupt sense register +#define GPIO_GPIO0IBE (*(pREG32 (0x50008008))) // Interrupt both edges register +#define GPIO_GPIO0IEV (*(pREG32 (0x5000800C))) // Interrupt event register +#define GPIO_GPIO0IE (*(pREG32 (0x50008010))) // Interrupt mask register +#define GPIO_GPIO0RIS (*(pREG32 (0x50008014))) // Raw interrupt status register +#define GPIO_GPIO0MIS (*(pREG32 (0x50008018))) // Masked interrupt status register +#define GPIO_GPIO0IC (*(pREG32 (0x5000801C))) // Interrupt clear register + +#define GPIO_GPIO1DATA (*(pREG32 (0x50013FFC))) // Port data register +#define GPIO_GPIO1DIR (*(pREG32 (0x50018000))) // Data direction register +#define GPIO_GPIO1IS (*(pREG32 (0x50018004))) // Interrupt sense register +#define GPIO_GPIO1IBE (*(pREG32 (0x50018008))) // Interrupt both edges register +#define GPIO_GPIO1IEV (*(pREG32 (0x5001800C))) // Interrupt event register +#define GPIO_GPIO1IE (*(pREG32 (0x50018010))) // Interrupt mask register +#define GPIO_GPIO1RIS (*(pREG32 (0x50018014))) // Raw interrupt status register +#define GPIO_GPIO1MIS (*(pREG32 (0x50018018))) // Masked interrupt status register +#define GPIO_GPIO1IC (*(pREG32 (0x5001801C))) // Interrupt clear register + +#define GPIO_GPIO2DATA (*(pREG32 (0x50023FFC))) // Port data register +#define GPIO_GPIO2DIR (*(pREG32 (0x50028000))) // Data direction register +#define GPIO_GPIO2IS (*(pREG32 (0x50028004))) // Interrupt sense register +#define GPIO_GPIO2IBE (*(pREG32 (0x50028008))) // Interrupt both edges register +#define GPIO_GPIO2IEV (*(pREG32 (0x5002800C))) // Interrupt event register +#define GPIO_GPIO2IE (*(pREG32 (0x50028010))) // Interrupt mask register +#define GPIO_GPIO2RIS (*(pREG32 (0x50028014))) // Raw interrupt status register +#define GPIO_GPIO2MIS (*(pREG32 (0x50028018))) // Masked interrupt status register +#define GPIO_GPIO2IC (*(pREG32 (0x5002801C))) // Interrupt clear register + +#define GPIO_GPIO3DATA (*(pREG32 (0x50033FFC))) // Port data register +#define GPIO_GPIO3DIR (*(pREG32 (0x50038000))) // Data direction register +#define GPIO_GPIO3IS (*(pREG32 (0x50038004))) // Interrupt sense register +#define GPIO_GPIO3IBE (*(pREG32 (0x50038008))) // Interrupt both edges register +#define GPIO_GPIO3IEV (*(pREG32 (0x5003800C))) // Interrupt event register +#define GPIO_GPIO3IE (*(pREG32 (0x50038010))) // Interrupt mask register +#define GPIO_GPIO3RIS (*(pREG32 (0x50038014))) // Raw interrupt status register +#define GPIO_GPIO3MIS (*(pREG32 (0x50038018))) // Masked interrupt status register +#define GPIO_GPIO3IC (*(pREG32 (0x5003801C))) // Interrupt clear register + +#define GPIO_IO_P0 ((unsigned int) 0x00000001) +#define GPIO_IO_P1 ((unsigned int) 0x00000002) +#define GPIO_IO_P2 ((unsigned int) 0x00000004) +#define GPIO_IO_P3 ((unsigned int) 0x00000008) +#define GPIO_IO_P4 ((unsigned int) 0x00000010) +#define GPIO_IO_P5 ((unsigned int) 0x00000020) +#define GPIO_IO_P6 ((unsigned int) 0x00000040) +#define GPIO_IO_P7 ((unsigned int) 0x00000080) +#define GPIO_IO_P8 ((unsigned int) 0x00000100) +#define GPIO_IO_P9 ((unsigned int) 0x00000200) +#define GPIO_IO_P10 ((unsigned int) 0x00000400) +#define GPIO_IO_P11 ((unsigned int) 0x00000800) +#define GPIO_IO_ALL ((unsigned int) 0x00000FFF) + +/*############################################################################## +## USB +##############################################################################*/ + +/* USB registers are defined in USB code */ +#define USB_BASE_ADDRESS (0x40020000) + +/* USB Device Interrupt Status Register */ +#define USB_DEVINTST (*(pREG32 (0x40020000))) +#define USB_DEVINTST_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTST_FRAME ((unsigned int) 0x00000001) // Frame interrupt +#define USB_DEVINTST_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTST_EP0 ((unsigned int) 0x00000002) // USB core interrupt for EP0 +#define USB_DEVINTST_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTST_EP1 ((unsigned int) 0x00000004) // USB core interrupt for EP1 +#define USB_DEVINTST_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTST_EP2 ((unsigned int) 0x00000008) // USB core interrupt for EP2 +#define USB_DEVINTST_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTST_EP3 ((unsigned int) 0x00000010) // USB core interrupt for EP3 +#define USB_DEVINTST_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTST_EP4 ((unsigned int) 0x00000020) // USB core interrupt for EP4 +#define USB_DEVINTST_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTST_EP5 ((unsigned int) 0x00000040) // USB core interrupt for EP5 +#define USB_DEVINTST_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTST_EP6 ((unsigned int) 0x00000080) // USB core interrupt for EP6 +#define USB_DEVINTST_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTST_EP7 ((unsigned int) 0x00000100) // USB core interrupt for EP7 +#define USB_DEVINTST_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTST_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTST_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTST_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTST_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTST_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTST_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTST_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTST_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTST_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Enable Register */ +#define USB_DEVINTEN (*(pREG32 (0x40020004))) +#define USB_DEVINTEN_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTEN_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTEN_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTEN_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTEN_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTEN_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTEN_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTEN_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTEN_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTEN_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTEN_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTEN_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTEN_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTEN_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTEN_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTEN_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTEN_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTEN_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTEN_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTEN_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTEN_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTEN_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTEN_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTEN_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTEN_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTEN_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTEN_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTEN_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Clear Register */ +#define USB_DEVINTCLR (*(pREG32 (0x40020008))) +#define USB_DEVINTCLR_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTCLR_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTCLR_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTCLR_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTCLR_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTCLR_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTCLR_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTCLR_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTCLR_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTCLR_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTCLR_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTCLR_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTCLR_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTCLR_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTCLR_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTCLR_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTCLR_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTCLR_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTCLR_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTCLR_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTCLR_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTCLR_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTCLR_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTCLR_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTCLR_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTCLR_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTCLR_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTCLR_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Set Register */ +#define USB_DEVINTSET (*(pREG32 (0x4002000C))) +#define USB_DEVINTSET_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTSET_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTSET_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTSET_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTSET_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTSET_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTSET_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTSET_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTSET_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTSET_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTSET_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTSET_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTSET_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTSET_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTSET_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTSET_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTSET_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTSET_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTSET_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTSET_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTSET_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTSET_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTSET_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTSET_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTSET_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTSET_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTSET_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTSET_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Command Code Register */ +#define USB_CMDCODE (*(pREG32 (0x40020010))) +#define USB_CMDCODE_CMD_PHASE_WRITE ((unsigned int) 0x00000100) +#define USB_CMDCODE_CMD_PHASE_READ ((unsigned int) 0x00000200) +#define USB_CMDCODE_CMD_PHASE_COMMAND ((unsigned int) 0x00000500) +#define USB_CMDCODE_CMD_PHASE_MASK ((unsigned int) 0x0000FF00) +#define USB_CMDCODE_CMD_CODE_MASK ((unsigned int) 0x00FF0000) +#define USB_CMDCODE_CMD_WDATA_MASK ((unsigned int) 0x00FF0000) + +/* USB Command Data Register */ +#define USB_CMDDATA (*(pREG32 (0x40020014))) +#define USB_CMDDATA_CMD_RDATA_MASK ((unsigned int) 0x000000FF) + +/* USB Receive Data Register */ +#define USB_RXDATA (*(pREG32 (0x40020018))) + +/* USB Transmit Data Register */ +#define USB_TXDATA (*(pREG32 (0x4002001C))) + +/* USB Receive Packet Length Register */ +#define USB_RXPLEN (*(pREG32 (0x40020020))) +#define USB_RXPLEN_PKT_LNGTH_MASK ((unsigned int) 0x000003FF) +#define USB_RXPLEN_DV_MASK ((unsigned int) 0x00000400) +#define USB_RXPLEN_DV ((unsigned int) 0x00000400) + +/* USB Transmit Packet Length Register */ +#define USB_TXPLEN (*(pREG32 (0x40020024))) +#define USB_TXPLEN_PKT_LNGTH_MASK 0x3FF + +/* USB Control Register */ +#define USB_CTRL (*(pREG32 (0x40020028))) +#define USB_CTRL_RD_EN_MASK ((unsigned int) 0x00000001) +#define USB_CTRL_RD_EN ((unsigned int) 0x00000001) +#define USB_CTRL_WR_EN_MASK ((unsigned int) 0x00000002) +#define USB_CTRL_WR_EN ((unsigned int) 0x00000002) +#define USB_CTRL_LOG_ENDPOINT_MASK ((unsigned int) 0x0000003C) + +/* USB Device FIQ Select Register */ +#define USB_DEVFIQSEL (*(pREG32 (0x4002002C))) +#define USB_DEVFIQSEL_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVFIQSEL_FRAME ((unsigned int) 0x00000001) +#define USB_DEVFIQSEL_BULKOUT_MASK ((unsigned int) 0x00000002) +#define USB_DEVFIQSEL_BULKOUT ((unsigned int) 0x00000002) +#define USB_DEVFIQSEL_BULKIN_MASK ((unsigned int) 0x00000004) +#define USB_DEVFIQSEL_BULKIN ((unsigned int) 0x00000004) + +/*############################################################################## +## UART +##############################################################################*/ + +#define UART_BASE_ADDRESS (0x40008000) + +#define UART_U0RBR (*(pREG32 (0x40008000))) // Receive buffer +#define UART_U0THR (*(pREG32 (0x40008000))) // Transmitter holding register +#define UART_U0DLL (*(pREG32 (0x40008000))) // Divisor latch LSB +#define UART_U0DLM (*(pREG32 (0x40008004))) // Divisor latch MSB +#define UART_U0IER (*(pREG32 (0x40008004))) // Interrupt enable +#define UART_U0IIR (*(pREG32 (0x40008008))) // Interrupt identification +#define UART_U0FCR (*(pREG32 (0x40008008))) // FIFO control +#define UART_U0MCR (*(pREG32 (0x40008010))) // Modem control +#define UART_U0LCR (*(pREG32 (0x4000800C))) // Line control +#define UART_U0LSR (*(pREG32 (0x40008014))) // Line status +#define UART_U0MSR (*(pREG32 (0x40008018))) // Modem status +#define UART_U0SCR (*(pREG32 (0x4000801C))) // Scratch pad +#define UART_U0ACR (*(pREG32 (0x40008020))) // Auto-baud control +#define UART_U0FDR (*(pREG32 (0x40008028))) // Fractional divider +#define UART_U0TER (*(pREG32 (0x40008030))) // Transmit enable +#define UART_U0RS485CTRL (*(pREG32 (0x4000804C))) // RS485 control register +#define UART_U0RS485ADRMATCH (*(pREG32 (0x40008050))) // RS485 address match +#define UART_U0RS485DLY (*(pREG32 (0x40008054))) // RS485 Delay value +#define UART_U0FIFOLVL (*(pREG32 (0x40008058))) // UART FIFO level + +#define UART_U0RBR_MASK ((unsigned int) 0x000000FF) + +#define UART_U0IER_RBR_Interrupt_MASK ((unsigned int) 0x00000001) // Enables the received data available interrupt +#define UART_U0IER_RBR_Interrupt_Enabled ((unsigned int) 0x00000001) +#define UART_U0IER_RBR_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_THRE_Interrupt_MASK ((unsigned int) 0x00000002) // Enables the THRE interrupt +#define UART_U0IER_THRE_Interrupt_Enabled ((unsigned int) 0x00000002) +#define UART_U0IER_THRE_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_RLS_Interrupt_MASK ((unsigned int) 0x00000004) // Enables the Rx line status interrupt +#define UART_U0IER_RLS_Interrupt_Enabled ((unsigned int) 0x00000004) +#define UART_U0IER_RLS_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_ABEOIntEn_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt +#define UART_U0IER_ABEOIntEn_Enabled ((unsigned int) 0x00000100) +#define UART_U0IER_ABEOIntEn_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_ABTOIntEn_MASK ((unsigned int) 0x00000200) // Auto-baud timeout interrupt +#define UART_U0IER_ABTOIntEn_Enabled ((unsigned int) 0x00000200) +#define UART_U0IER_ABTOIntEn_Disabled ((unsigned int) 0x00000000) + +#define UART_U0IIR_IntStatus_MASK ((unsigned int) 0x00000001) // Interrupt status +#define UART_U0IIR_IntStatus_InterruptPending ((unsigned int) 0x00000001) +#define UART_U0IIR_IntStatus_NoInterruptPending ((unsigned int) 0x00000000) +#define UART_U0IIR_IntId_MASK ((unsigned int) 0x0000000E) // Interrupt identification +#define UART_U0IIR_IntId_RLS ((unsigned int) 0x00000006) // Receive line status +#define UART_U0IIR_IntId_RDA ((unsigned int) 0x00000004) // Receive data available +#define UART_U0IIR_IntId_CTI ((unsigned int) 0x0000000C) // Character time-out indicator +#define UART_U0IIR_IntId_THRE ((unsigned int) 0x00000002) // THRE interrupt +#define UART_U0IIR_IntId_MODEM ((unsigned int) 0x00000000) // Modem interrupt +#define UART_U0IIR_FIFO_Enable_MASK ((unsigned int) 0x000000C0) +#define UART_U0IIR_ABEOInt_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt +#define UART_U0IIR_ABEOInt ((unsigned int) 0x00000100) +#define UART_U0IIR_ABTOInt_MASK ((unsigned int) 0x00000200) // Auto-baud time-out interrupt +#define UART_U0IIR_ABTOInt ((unsigned int) 0x00000200) + +#define UART_U0FCR_FIFO_Enable_MASK ((unsigned int) 0x00000001) // UART FIFOs enabled/disabled +#define UART_U0FCR_FIFO_Enabled ((unsigned int) 0x00000001) +#define UART_U0FCR_FIFO_Disabled ((unsigned int) 0x00000000) +#define UART_U0FCR_Rx_FIFO_Reset_MASK ((unsigned int) 0x00000002) +#define UART_U0FCR_Rx_FIFO_Reset ((unsigned int) 0x00000002) // Clear Rx FIFO +#define UART_U0FCR_Tx_FIFO_Reset_MASK ((unsigned int) 0x00000004) +#define UART_U0FCR_Tx_FIFO_Reset ((unsigned int) 0x00000004) // Clear Tx FIFO +#define UART_U0FCR_Rx_Trigger_Level_Select_MASK ((unsigned int) 0x000000C0) // Chars written before before interrupt +#define UART_U0FCR_Rx_Trigger_Level_Select_1Char ((unsigned int) 0x00000000) +#define UART_U0FCR_Rx_Trigger_Level_Select_4Char ((unsigned int) 0x00000040) +#define UART_U0FCR_Rx_Trigger_Level_Select_8Char ((unsigned int) 0x00000080) +#define UART_U0FCR_Rx_Trigger_Level_Select_12Char ((unsigned int) 0x000000C0) + +#define UART_U0MCR_DTR_Control_MASK ((unsigned int) 0x00000001) // Source for modem output pin DTR +#define UART_U0MCR_DTR_Control ((unsigned int) 0x00000001) +#define UART_U0MCR_RTS_Control_MASK ((unsigned int) 0x00000002) // Source for modem output pin RTS +#define UART_U0MCR_RTS_Control ((unsigned int) 0x00000002) +#define UART_U0MCR_Loopback_Mode_Select_MASK ((unsigned int) 0x00000010) // Diagnostic loopback mode +#define UART_U0MCR_Loopback_Mode_Select_Enabled ((unsigned int) 0x00000010) +#define UART_U0MCR_Loopback_Mode_Select_Disabled ((unsigned int) 0x00000000) +#define UART_U0MCR_RTSen_MASK ((unsigned int) 0x00000040) // Disable auto-rts flow control +#define UART_U0MCR_RTSen_Enabled ((unsigned int) 0x00000040) +#define UART_U0MCR_RTSen_Disabled ((unsigned int) 0x00000000) +#define UART_U0MCR_CTSen_MASK ((unsigned int) 0x00000080) // Disable auto-cts flow control +#define UART_U0MCR_CTSen_Enabled ((unsigned int) 0x00000080) +#define UART_U0MCR_CTSen_Disabled ((unsigned int) 0x00000000) + +#define UART_U0LCR_Word_Length_Select_MASK ((unsigned int) 0x00000003) // Word Length Selector +#define UART_U0LCR_Word_Length_Select_5Chars ((unsigned int) 0x00000000) +#define UART_U0LCR_Word_Length_Select_6Chars ((unsigned int) 0x00000001) +#define UART_U0LCR_Word_Length_Select_7Chars ((unsigned int) 0x00000002) +#define UART_U0LCR_Word_Length_Select_8Chars ((unsigned int) 0x00000003) +#define UART_U0LCR_Stop_Bit_Select_MASK ((unsigned int) 0x00000004) // Stop bit select +#define UART_U0LCR_Stop_Bit_Select_1Bits ((unsigned int) 0x00000000) +#define UART_U0LCR_Stop_Bit_Select_2Bits ((unsigned int) 0x00000004) +#define UART_U0LCR_Parity_Enable_MASK ((unsigned int) 0x00000008) // Parity enable +#define UART_U0LCR_Parity_Enabled ((unsigned int) 0x00000008) +#define UART_U0LCR_Parity_Disabled ((unsigned int) 0x00000000) +#define UART_U0LCR_Parity_Select_MASK ((unsigned int) 0x00000030) // Parity select +#define UART_U0LCR_Parity_Select_OddParity ((unsigned int) 0x00000000) +#define UART_U0LCR_Parity_Select_EvenParity ((unsigned int) 0x00000010) +#define UART_U0LCR_Parity_Select_Forced1 ((unsigned int) 0x00000020) +#define UART_U0LCR_Parity_Select_Forced0 ((unsigned int) 0x00000030) +#define UART_U0LCR_Break_Control_MASK ((unsigned int) 0x00000040) // Break transmission control +#define UART_U0LCR_Break_Control_Enabled ((unsigned int) 0x00000040) +#define UART_U0LCR_Break_Control_Disabled ((unsigned int) 0x00000000) +#define UART_U0LCR_Divisor_Latch_Access_MASK ((unsigned int) 0x00000080) // Divisor latch access +#define UART_U0LCR_Divisor_Latch_Access_Enabled ((unsigned int) 0x00000080) +#define UART_U0LCR_Divisor_Latch_Access_Disabled ((unsigned int) 0x00000000) + +#define UART_U0LSR_RDR_MASK ((unsigned int) 0x00000001) // Receiver data ready +#define UART_U0LSR_RDR_EMPTY ((unsigned int) 0x00000000) // U0RBR is empty +#define UART_U0LSR_RDR_DATA ((unsigned int) 0x00000001) // U0RBR contains valid data +#define UART_U0LSR_OE_MASK ((unsigned int) 0x00000002) // Overrun error +#define UART_U0LSR_OE ((unsigned int) 0x00000002) +#define UART_U0LSR_PE_MASK ((unsigned int) 0x00000004) // Parity error +#define UART_U0LSR_PE ((unsigned int) 0x00000004) +#define UART_U0LSR_FE_MASK ((unsigned int) 0x00000008) // Framing error +#define UART_U0LSR_FE ((unsigned int) 0x00000008) +#define UART_U0LSR_BI_MASK ((unsigned int) 0x00000010) // Break interrupt +#define UART_U0LSR_BI ((unsigned int) 0x00000010) +#define UART_U0LSR_THRE_MASK ((unsigned int) 0x00000020) // Transmitter holding register empty +#define UART_U0LSR_THRE ((unsigned int) 0x00000020) +#define UART_U0LSR_TEMT_MASK ((unsigned int) 0x00000040) // Transmitter empty +#define UART_U0LSR_TEMT ((unsigned int) 0x00000040) +#define UART_U0LSR_RXFE_MASK ((unsigned int) 0x00000080) // Error in Rx FIFO +#define UART_U0LSR_RXFE ((unsigned int) 0x00000080) + +#define UART_U0MSR_Delta_CTS_MASK ((unsigned int) 0x00000001) // State change of input CTS +#define UART_U0MSR_Delta_CTS ((unsigned int) 0x00000001) +#define UART_U0MSR_Delta_DSR_MASK ((unsigned int) 0x00000002) // State change of input DSR +#define UART_U0MSR_Delta_DSR ((unsigned int) 0x00000002) +#define UART_U0MSR_Trailing_Edge_RI_MASK ((unsigned int) 0x00000004) // Low to high transition of input RI +#define UART_U0MSR_Trailing_Edge_RI ((unsigned int) 0x00000004) +#define UART_U0MSR_Delta_DCD_MASK ((unsigned int) 0x00000008) // State change of input DCD +#define UART_U0MSR_Delta_DCD ((unsigned int) 0x00000008) +#define UART_U0MSR_CTS_MASK ((unsigned int) 0x00000010) // Clear to send state +#define UART_U0MSR_CTS ((unsigned int) 0x00000010) +#define UART_U0MSR_DSR_MASK ((unsigned int) 0x00000020) // Data set ready state +#define UART_U0MSR_DSR ((unsigned int) 0x00000020) +#define UART_U0MSR_RI_MASK ((unsigned int) 0x00000040) // Ring indicator state +#define UART_U0MSR_RI ((unsigned int) 0x00000040) +#define UART_U0MSR_DCD_MASK ((unsigned int) 0x00000080) // Data carrier detect state +#define UART_U0MSR_DCD ((unsigned int) 0x00000080) + +#define UART_U0ACR_Start_MASK ((unsigned int) 0x00000001) // Auto-baud start/stop +#define UART_U0ACR_Start ((unsigned int) 0x00000001) +#define UART_U0ACR_Stop ((unsigned int) 0x00000000) +#define UART_U0ACR_Mode_MASK ((unsigned int) 0x00000002) // Auto-baud mode select +#define UART_U0ACR_Mode_Mode1 ((unsigned int) 0x00000000) +#define UART_U0ACR_Mode_Mode2 ((unsigned int) 0x00000002) +#define UART_U0ACR_AutoRestart_MASK ((unsigned int) 0x00000004) +#define UART_U0ACR_AutoRestart_NoRestart ((unsigned int) 0x00000000) +#define UART_U0ACR_AutoRestart_Restart ((unsigned int) 0x00000004) // Restart in case of time-out +#define UART_U0ACR_ABEOIntClr_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt clear bit +#define UART_U0ACR_ABEOIntClr ((unsigned int) 0x00000100) +#define UART_U0ACR_ABTOIntClr_MASK ((unsigned int) 0x00000200) // Auto-baud timeout interrupt clear bit +#define UART_U0ACR_ABTOIntClr ((unsigned int) 0x00000200) + +#define UART_U0FDR_DIVADDVAL_MASK ((unsigned int) 0x0000000F) // Fractional divider: prescaler register +#define UART_U0FDR_MULVAL_MASK ((unsigned int) 0x000000F0) // Fractional divider: prescaler multiplier + +#define UART_U0TER_TXEN_MASK ((unsigned int) 0x00000080) // UART transmit enable +#define UART_U0TER_TXEN_Enabled ((unsigned int) 0x00000080) +#define UART_U0TER_TXEN_Disabled ((unsigned int) 0x00000000) + +#define UART_U0RS485CTRL_NMMEN_MASK ((unsigned int) 0x00000001) // Normal multi-drop mode +#define UART_U0RS485CTRL_NMMEN ((unsigned int) 0x00000001) +#define UART_U0RS485CTRL_RXDIS_MASK ((unsigned int) 0x00000002) // Receiver +#define UART_U0RS485CTRL_RXDIS ((unsigned int) 0x00000002) +#define UART_U0RS485CTRL_AADEN_MASK ((unsigned int) 0x00000004) // Auto-address detect +#define UART_U0RS485CTRL_AADEN ((unsigned int) 0x00000004) +#define UART_U0RS485CTRL_SEL_MASK ((unsigned int) 0x00000008) +#define UART_U0RS485CTRL_SEL_RTS ((unsigned int) 0x00000000) // Use RTS for direction control +#define UART_U0RS485CTRL_SEL_DTS ((unsigned int) 0x00000008) // Use DTS for direction control +#define UART_U0RS485CTRL_DCTRL_MASK ((unsigned int) 0x00000010) // Enable/Disable auto-direction control +#define UART_U0RS485CTRL_DCTRL_Disabled ((unsigned int) 0x00000000) +#define UART_U0RS485CTRL_DCTRL_Enabled ((unsigned int) 0x00000010) +#define UART_U0RS485CTRL_OINV_MASK ((unsigned int) 0x00000020) // Reverse polarity of direction control signal on RTS/DTR pin +#define UART_U0RS485CTRL_OINV_Normal ((unsigned int) 0x00000000) +#define UART_U0RS485CTRL_OINV_Inverted ((unsigned int) 0x00000020) + +#define UART_U0FIFOLVL_RXFIFOLVL_MASK ((unsigned int) 0x0000000F) +#define UART_U0FIFOLVL_RXFIFOLVL_Empty ((unsigned int) 0x00000000) +#define UART_U0FIFOLVL_RXFIFOLVL_Full ((unsigned int) 0x0000000F) +#define UART_U0FIFOLVL_TXFIFOLVL_MASK ((unsigned int) 0x00000F00) +#define UART_U0FIFOLVL_TXFIFOLVL_Empty ((unsigned int) 0x00000000) +#define UART_U0FIFOLVL_TXFIFOLVL_Full ((unsigned int) 0x00000F00) + +/*############################################################################## +## SSP - Synchronous Serial Port +##############################################################################*/ + +#define SSP_SSP0_BASE_ADDRESS (0x40040000) + +#define SSP_SSP0CR0 (*(pREG32 (0x40040000))) // Control register 0 +#define SSP_SSP0CR1 (*(pREG32 (0x40040004))) // Control register 1 +#define SSP_SSP0DR (*(pREG32 (0x40040008))) // Data register +#define SSP_SSP0SR (*(pREG32 (0x4004000C))) // Status register +#define SSP_SSP0CPSR (*(pREG32 (0x40040010))) // Clock prescale register +#define SSP_SSP0IMSC (*(pREG32 (0x40040014))) // Interrupt mask set/clear register +#define SSP_SSP0RIS (*(pREG32 (0x40040018))) // Raw interrupt status register +#define SSP_SSP0MIS (*(pREG32 (0x4004001C))) // Masked interrupt status register +#define SSP_SSP0ICR (*(pREG32 (0x40040020))) // SSPICR interrupt clear register + +/* SSP0CR0 (SSP0 Control Register 0) + This register controls the basic operation of the SSP controller. */ + +#define SSP_SSP0CR0_DSS_MASK ((unsigned int) 0x0000000F) // Data size select +#define SSP_SSP0CR0_DSS_4BIT ((unsigned int) 0x00000003) +#define SSP_SSP0CR0_DSS_5BIT ((unsigned int) 0x00000004) +#define SSP_SSP0CR0_DSS_6BIT ((unsigned int) 0x00000005) +#define SSP_SSP0CR0_DSS_7BIT ((unsigned int) 0x00000006) +#define SSP_SSP0CR0_DSS_8BIT ((unsigned int) 0x00000007) +#define SSP_SSP0CR0_DSS_9BIT ((unsigned int) 0x00000008) +#define SSP_SSP0CR0_DSS_10BIT ((unsigned int) 0x00000009) +#define SSP_SSP0CR0_DSS_11BIT ((unsigned int) 0x0000000A) +#define SSP_SSP0CR0_DSS_12BIT ((unsigned int) 0x0000000B) +#define SSP_SSP0CR0_DSS_13BIT ((unsigned int) 0x0000000C) +#define SSP_SSP0CR0_DSS_14BIT ((unsigned int) 0x0000000D) +#define SSP_SSP0CR0_DSS_15BIT ((unsigned int) 0x0000000E) +#define SSP_SSP0CR0_DSS_16BIT ((unsigned int) 0x0000000F) +#define SSP_SSP0CR0_FRF_MASK ((unsigned int) 0x00000030) // Frame format +#define SSP_SSP0CR0_FRF_SPI ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_FRF_TI ((unsigned int) 0x00000010) +#define SSP_SSP0CR0_FRF_MWIRE ((unsigned int) 0x00000020) +#define SSP_SSP0CR0_CPOL_MASK ((unsigned int) 0x00000040) // Clock out polarity +#define SSP_SSP0CR0_CPOL_LOW ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_CPOL_HIGH ((unsigned int) 0x00000040) +#define SSP_SSP0CR0_CPHA_MASK ((unsigned int) 0x00000080) // Clock out phase +#define SSP_SSP0CR0_CPHA_FIRST ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_CPHA_SECOND ((unsigned int) 0x00000080) + +/* Serial Clock Rate. The number of prescaler-output clocks per + bit on the bus, minus one. Given that CPSDVSR is the + prescale divider, and the APB clock PCLK clocks the + prescaler, the bit frequency is PCLK / (CPSDVSR — [SCR+1]). */ + +#define SSP_SSP0CR0_SCR_MASK ((unsigned int) 0x0000FF00) // Serial clock rate +#define SSP_SSP0CR0_SCR_1 ((unsigned int) 0x00000100) +#define SSP_SSP0CR0_SCR_2 ((unsigned int) 0x00000200) +#define SSP_SSP0CR0_SCR_3 ((unsigned int) 0x00000300) +#define SSP_SSP0CR0_SCR_4 ((unsigned int) 0x00000400) +#define SSP_SSP0CR0_SCR_5 ((unsigned int) 0x00000500) +#define SSP_SSP0CR0_SCR_6 ((unsigned int) 0x00000600) +#define SSP_SSP0CR0_SCR_7 ((unsigned int) 0x00000700) +#define SSP_SSP0CR0_SCR_8 ((unsigned int) 0x00000800) +#define SSP_SSP0CR0_SCR_9 ((unsigned int) 0x00000900) +#define SSP_SSP0CR0_SCR_10 ((unsigned int) 0x00000A00) +#define SSP_SSP0CR0_SCR_11 ((unsigned int) 0x00000B00) +#define SSP_SSP0CR0_SCR_12 ((unsigned int) 0x00000C00) +#define SSP_SSP0CR0_SCR_13 ((unsigned int) 0x00000D00) +#define SSP_SSP0CR0_SCR_14 ((unsigned int) 0x00000E00) +#define SSP_SSP0CR0_SCR_15 ((unsigned int) 0x00000F00) +#define SSP_SSP0CR0_SCR_16 ((unsigned int) 0x00001000) + +/* SSP0CR1 (SSP0 Control Register 1) + This register controls certain aspects of the operation of the SSP controller. */ + +#define SSP_SSP0CR1_LBM_MASK ((unsigned int) 0x00000001) // Loop back mode +#define SSP_SSP0CR1_LBM_NORMAL ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_LBM_INVERTED ((unsigned int) 0x00000001) // MISO/MOSI are reversed +#define SSP_SSP0CR1_SSE_MASK ((unsigned int) 0x00000002) // SSP enable +#define SSP_SSP0CR1_SSE_DISABLED ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_SSE_ENABLED ((unsigned int) 0x00000002) +#define SSP_SSP0CR1_MS_MASK ((unsigned int) 0x00000004) // Master/Slave Mode +#define SSP_SSP0CR1_MS_MASTER ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_MS_SLAVE ((unsigned int) 0x00000004) +#define SSP_SSP0CR1_SOD_MASK ((unsigned int) 0x00000008) // Slave output disable + +/* SSP0DR (SSP0 Data Register) + Software can write data to be transmitted to this register, and read data that has been + received. */ + +#define SSP_SSP0DR_MASK ((unsigned int) 0x0000FFFF) // Data + +/* SSP0SR (SSP0 Status Register) + This read-only register reflects the current status of the SSP controller. */ + +#define SSP_SSP0SR_TFE_MASK ((unsigned int) 0x00000001) // Transmit FIFO empty +#define SSP_SSP0SR_TFE_EMPTY ((unsigned int) 0x00000001) +#define SSP_SSP0SR_TFE_NOTEMPTY ((unsigned int) 0x00000000) +#define SSP_SSP0SR_TNF_MASK ((unsigned int) 0x00000002) // Transmit FIFO not full +#define SSP_SSP0SR_TNF_NOTFULL ((unsigned int) 0x00000002) +#define SSP_SSP0SR_TNF_FULL ((unsigned int) 0x00000000) +#define SSP_SSP0SR_RNE_MASK ((unsigned int) 0x00000004) // Receive FIFO not empty +#define SSP_SSP0SR_RNE_NOTEMPTY ((unsigned int) 0x00000004) +#define SSP_SSP0SR_RNE_EMPTY ((unsigned int) 0x00000000) +#define SSP_SSP0SR_RFF_MASK ((unsigned int) 0x00000008) // Receive FIFO full +#define SSP_SSP0SR_RFF_FULL ((unsigned int) 0x00000008) +#define SSP_SSP0SR_RFF_NOTFULL ((unsigned int) 0x00000000) +#define SSP_SSP0SR_BSY_MASK ((unsigned int) 0x00000010) // Busy Flag +#define SSP_SSP0SR_BSY_IDLE ((unsigned int) 0x00000000) +#define SSP_SSP0SR_BSY_BUSY ((unsigned int) 0x00000010) + +/* SSP0CPSR (SSP0 Clock Prescale Register) + This register controls the factor by which the Prescaler divides the SSP peripheral clock + SSP_PCLK to yield the prescaler clock that is, in turn, divided by the SCR factor in + SSP0CR0, to determine the bit clock. */ + +#define SSP_SSP0CPSR_CPSDVSR_MASK ((unsigned int) 0x000000FF) +#define SSP_SSP0CPSR_CPSDVSR_DIV2 ((unsigned int) 0x00000002) +#define SSP_SSP0CPSR_CPSDVSR_DIV4 ((unsigned int) 0x00000004) +#define SSP_SSP0CPSR_CPSDVSR_DIV10 ((unsigned int) 0x0000000A) +#define SSP_SSP0CPSR_CPSDVSR_DIV12 ((unsigned int) 0x0000000C) +#define SSP_SSP0CPSR_CPSDVSR_DIV16 ((unsigned int) 0x00000010) +#define SSP_SSP0CPSR_CPSDVSR_DIV20 ((unsigned int) 0x00000014) + +/* SSP0IMSC (SSP0 Interrupt Mask Set/Clear Register) + This register controls whether each of the four possible interrupt conditions in the SSP + controller are enabled. Note that ARM uses the word “masked” in the opposite sense from + classic computer terminology, in which “masked” meant “disabled”. ARM uses the word + “masked” to mean “enabled”. To avoid confusion we will not use the word “masked”. */ + +#define SSP_SSP0IMSC_RORIM_MASK ((unsigned int) 0x00000001) // Receive overrun interrupt +#define SSP_SSP0IMSC_RORIM_ENBL ((unsigned int) 0x00000001) +#define SSP_SSP0IMSC_RORIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_RTIM_MASK ((unsigned int) 0x00000002) // Receive timeout interrupt +#define SSP_SSP0IMSC_RTIM_ENBL ((unsigned int) 0x00000002) +#define SSP_SSP0IMSC_RTIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_RXIM_MASK ((unsigned int) 0x00000004) // Rx FIFO >= 1/2 full interrupt +#define SSP_SSP0IMSC_RXIM_ENBL ((unsigned int) 0x00000004) +#define SSP_SSP0IMSC_RXIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_TXIM_MASK ((unsigned int) 0x00000008) // Tx FIFO >= 1/2 empty interrupt +#define SSP_SSP0IMSC_TXIM_ENBL ((unsigned int) 0x00000008) +#define SSP_SSP0IMSC_TXIM_DSBL ((unsigned int) 0x00000000) + +/* SSP0RIS (SSP0 Raw Interrupt Status Register) + This read-only register contains a 1 for each interrupt condition that is asserted, + regardless of whether or not the interrupt is enabled in the SSP0IMSC. */ + +#define SSP_SSP0RIS_RORRIS_MASK ((unsigned int) 0x00000001) // Frame received while Rx FIFO full +#define SSP_SSP0RIS_RORRIS_RCVD ((unsigned int) 0x00000001) +#define SSP_SSP0RIS_RTRIS_MASK ((unsigned int) 0x00000002) // Rx FIFO not empty no read within timeout +#define SSP_SSP0RIS_RTRIS_NOTEMPTY ((unsigned int) 0x00000002) +#define SSP_SSP0RIS_RXRIS_MASK ((unsigned int) 0x00000004) // Rx FIFO >= half full +#define SSP_SSP0RIS_RXRIS_HALFFULL ((unsigned int) 0x00000004) +#define SSP_SSP0RIS_TXRIS_MASK ((unsigned int) 0x00000008) // Tx FIF0 >= half-empty +#define SSP_SSP0RIS_TXRIS_HALFEMPTY ((unsigned int) 0x00000008) + +/* SSP0MIS (SSP0 Masked Interrupt Status Register) + This read-only register contains a 1 for each interrupt condition that is asserted and + enabled in the SSP0IMSC. When an SSP interrupt occurs, the interrupt service routine + should read this register to determine the cause(s) of the interrupt. */ + +#define SSP_SSP0MIS_RORMIS_MASK ((unsigned int) 0x00000001) // Frame received while Rx FIFO full +#define SSP_SSP0MIS_RORMIS_FRMRCVD ((unsigned int) 0x00000001) +#define SSP_SSP0MIS_RTMIS_MASK ((unsigned int) 0x00000002) // Rx FIFO not empty no read withing timeout +#define SSP_SSP0MIS_RTMIS_NOTEMPTY ((unsigned int) 0x00000002) +#define SSP_SSP0MIS_RXMIS_MASK ((unsigned int) 0x00000004) // Rx FIFO >= half full +#define SSP_SSP0MIS_RXMIS_HALFFULL ((unsigned int) 0x00000004) +#define SSP_SSP0MIS_TXMIS_MASK ((unsigned int) 0x00000008) // Tx FIFO >= half-empty +#define SSP_SSP0MIS_TXMIS_HALFEMPTY ((unsigned int) 0x00000008) + +/* SSP0ICR (SSP0 Interrupt Clear Register) + Software can write one or more one(s) to this write-only register, to clear the + corresponding interrupt condition(s) in the SSP controller. Note that the other two interrupt + conditions can be cleared by writing or reading the appropriate FIFO, or disabled by + clearing the corresponding bit in SSP0IMSC. */ + +#define SSP_SSP0ICR_RORIC_MASK ((unsigned int) 0x00000001) // Clears RORIC interrupt flag +#define SSP_SSP0ICR_RORIC_CLEAR ((unsigned int) 0x00000001) +#define SSP_SSP0ICR_RTIC_MASK ((unsigned int) 0x00000002) // Clear Rx FIFO not empty/no read flag +#define SSP_SSP0ICR_RTIC_CLEAR ((unsigned int) 0x00000002) + +/*############################################################################## +## I2C +##############################################################################*/ + +#define I2C_BASE_ADDRESS (0x40000000) + +#define I2C_I2CCONSET (*(pREG32 (0x40000000))) // I2C control set register +#define I2C_I2CSTAT (*(pREG32 (0x40000004))) // I2C status register +#define I2C_I2CDAT (*(pREG32 (0x40000008))) // I2C data register +#define I2C_I2CADR0 (*(pREG32 (0x4000000C))) // I2C slave address register +#define I2C_I2CSCLH (*(pREG32 (0x40000010))) // I2C SCL HIGH/LOW duty cycle register +#define I2C_I2CSCLL (*(pREG32 (0x40000014))) +#define I2C_I2CCONCLR (*(pREG32 (0x40000018))) // I2C control clear register +#define I2C_I2CMMCTRL (*(pREG32 (0x4000001C))) // I2C monitor control register +#define I2C_I2CADR1 (*(pREG32 (0x40000020))) // I2C slave address register 1 +#define I2C_I2CADR2 (*(pREG32 (0x40000024))) // I2C slave address register 2 +#define I2C_I2CADR3 (*(pREG32 (0x40000028))) // I2C slave address register 3 +#define I2C_I2CDATA_BUFFER (*(pREG32 (0x4000002C))) // I2C data buffer register +#define I2C_I2CMASK0 (*(pREG32 (0x40000030))) // I2C mask register 0 +#define I2C_I2CMASK1 (*(pREG32 (0x40000034))) // I2C mask register 1 +#define I2C_I2CMASK2 (*(pREG32 (0x40000038))) // I2C mask register 2 +#define I2C_I2CMASK3 (*(pREG32 (0x4000003C))) // I2C mask register 3 + +/* I2CCONSET (I2C Control Set register) + The I2CONSET registers control setting of bits in the I2CON register that controls + operation of the I2C interface. Writing a one to a bit of this register causes the + corresponding bit in the I2C control register to be set. Writing a zero has no effect. */ + +#define I2C_I2CCONSET_AA_MASK ((unsigned int) 0x00000004) +#define I2C_I2CCONSET_AA ((unsigned int) 0x00000004) // Asset acknowlegde flag +#define I2C_I2CCONSET_SI_MASK ((unsigned int) 0x00000008) +#define I2C_I2CCONSET_SI ((unsigned int) 0x00000008) // I2C interrupt flag +#define I2C_I2CCONSET_STO_MASK ((unsigned int) 0x00000010) +#define I2C_I2CCONSET_STO ((unsigned int) 0x00000010) // Stop flag +#define I2C_I2CCONSET_STA_MASK ((unsigned int) 0x00000020) +#define I2C_I2CCONSET_STA ((unsigned int) 0x00000020) // Start flag +#define I2C_I2CCONSET_I2EN_MASK ((unsigned int) 0x00000040) +#define I2C_I2CCONSET_I2EN ((unsigned int) 0x00000040) // I2C interface enable + +/* I2CSTAT (I2C Status register) + Each I2C Status register reflects the condition of the corresponding I2C interface. The I2C + Status register is Read-Only. */ + +#define I2C_I2CSTAT_Status_MASK ((unsigned int) 0x000000F8) // Status information + +/* I2CADR0 (I2C Slave Address register) + These registers are readable and writable and are only used when an I2C interface is set + to slave mode. */ + +#define I2C_I2CADR0_GC_MASK ((unsigned int) 0x00000001) +#define I2C_I2CADR0_GC ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR0_Address_MASK ((unsigned int) 0x000000FE) // I2C device address for slave mode + +/* I2CCONCLR (I2C Control Clear register) + The I2CONCLR registers control clearing of bits in the I2CON register that controls + operation of the I2C interface. Writing a one to a bit of this register causes the + corresponding bit in the I2C control register to be cleared. Writing a zero has no effect. */ + +#define I2C_I2CCONCLR_AAC_MASK ((unsigned int) 0x00000004) // Assert acknowledge clear bit +#define I2C_I2CCONCLR_AAC ((unsigned int) 0x00000004) +#define I2C_I2CCONCLR_SIC_MASK ((unsigned int) 0x00000008) // I2C interrupt clear bit +#define I2C_I2CCONCLR_SIC ((unsigned int) 0x00000008) +#define I2C_I2CCONCLR_STAC_MASK ((unsigned int) 0x00000020) // Start flag clear bit +#define I2C_I2CCONCLR_STAC ((unsigned int) 0x00000020) +#define I2C_I2CCONCLR_I2ENC_MASK ((unsigned int) 0x00000040) // I2C interface disable bit +#define I2C_I2CCONCLR_I2ENC ((unsigned int) 0x00000040) + +/* I2CMMCTRL (I2C Monitor mode control register) + This register controls the Monitor mode which allows the I2C module to monitor traffic on + the I2C bus without actually participating in traffic or interfering with the I2C bus. */ + +#define I2C_I2CMMCTRL_MM_ENA_MASK ((unsigned int) 0x00000001) // Monitor mode enable +#define I2C_I2CMMCTRL_MM_ENA_ENABLED ((unsigned int) 0x00000001) +#define I2C_I2CMMCTRL_MM_ENA_DISABLED ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_ENA_SCL_MASK ((unsigned int) 0x00000002) // SCL output enable +#define I2C_I2CMMCTRL_ENA_SCL_HOLDLOW ((unsigned int) 0x00000002) +#define I2C_I2CMMCTRL_ENA_SCL_FORCEHIGH ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_MATCH_ALL_MASK ((unsigned int) 0x00000008) // Select interrupt register match +#define I2C_I2CMMCTRL_MATCH_ALL_NORMAL ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_MATCH_ALL_ANYADDRESS ((unsigned int) 0x00000008) + +/* I2CADR1..3 (I2C Slave Address registers) + These registers are readable and writable and are only used when an I2C interface is set + to slave mode. In master mode, this register has no effect. The LSB of I2ADR is the + General Call bit. When this bit is set, the General Call address (0x00) is recognized. */ + +#define I2C_I2CADR1_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR1_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR1_Address_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CADR2_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR2_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR2_Address_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CADR3_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR3_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR3_Address_MASK ((unsigned int) 0x000000FE) + +/* I2CMASK0..3 (I2C Mask registers) */ + +#define I2C_I2CMASK0_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK1_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK2_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK3_MASK_MASK ((unsigned int) 0x000000FE) + +/*############################################################################## +## 16-Bit Timers (CT16B0/1) +##############################################################################*/ + +#define TMR_CT16B0_BASE_ADDRESS (0x4000C000) + +#define TMR_TMR16B0IR (*(pREG32 (0x4000C000))) // Interrupt register +#define TMR_TMR16B0TCR (*(pREG32 (0x4000C004))) // Timer control register +#define TMR_TMR16B0TC (*(pREG32 (0x4000C008))) // Timer counter +#define TMR_TMR16B0PR (*(pREG32 (0x4000C00C))) // Prescale register +#define TMR_TMR16B0PC (*(pREG32 (0x4000C010))) // Prescale counter register +#define TMR_TMR16B0MCR (*(pREG32 (0x4000C014))) // Match control register +#define TMR_TMR16B0MR0 (*(pREG32 (0x4000C018))) // Match register 0 +#define TMR_TMR16B0MR1 (*(pREG32 (0x4000C01C))) // Match register 1 +#define TMR_TMR16B0MR2 (*(pREG32 (0x4000C020))) // Match register 2 +#define TMR_TMR16B0MR3 (*(pREG32 (0x4000C024))) // Match register 3 +#define TMR_TMR16B0CCR (*(pREG32 (0x4000C028))) // Capture control register +#define TMR_TMR16B0CR0 (*(pREG32 (0x4000C02C))) // Capture register +#define TMR_TMR16B0EMR (*(pREG32 (0x4000C03C))) // External match register +#define TMR_TMR16B0CTCR (*(pREG32 (0x4000C070))) // Count control register +#define TMR_TMR16B0PWMC (*(pREG32 (0x4000C074))) // PWM control register + +#define TMR_TMR16B0IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR16B0IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR16B0IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR16B0IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR16B0IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR16B0IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR16B0IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR16B0IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR16B0IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR16B0IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR16B0IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR16B0TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR16B0TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B0TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR16B0MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR16B0MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR16B0MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR16B0MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B0MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR16B0MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B0MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR16B0MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR16B0MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR16B0MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR16B0MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR16B0MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR16B0MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR16B0MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR16B0MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR16B0MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR16B0MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR16B0MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR16B0MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR16B0MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR16B0MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR16B0MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR16B0MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B0CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR16B0CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR16B0CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR16B0CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B0CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B0EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR16B0EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR16B0EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR16B0EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR16B0EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR16B0EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR16B0EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR16B0EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR16B0EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR16B0EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR16B0EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR16B0EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR16B0EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR16B0EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR16B0EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR16B0EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR16B0EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR16B0EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR16B0EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR16B0EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR16B0EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR16B0EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR16B0EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR16B0EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR16B0CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR16B0CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR16B0CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR16B0CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR16B0CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR16B0CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR16B0CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR16B0PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR16B0PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT16Bn_MAT0 +#define TMR_TMR16B0PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B0PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT16Bn_MAT1 +#define TMR_TMR16B0PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR16B0PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT16Bn_MAT2 +#define TMR_TMR16B0PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR16B0PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B0PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +#define TMR_CT16B1_BASE_ADDRESS (0x40010000) + +#define TMR_TMR16B1IR (*(pREG32 (0x40010000))) // Interrupt register +#define TMR_TMR16B1TCR (*(pREG32 (0x40010004))) // Timer control register +#define TMR_TMR16B1TC (*(pREG32 (0x40010008))) // Timer counter +#define TMR_TMR16B1PR (*(pREG32 (0x4001000C))) // Prescale register +#define TMR_TMR16B1PC (*(pREG32 (0x40010010))) // Prescale counter register +#define TMR_TMR16B1MCR (*(pREG32 (0x40010014))) // Match control register +#define TMR_TMR16B1MR0 (*(pREG32 (0x40010018))) // Match register 0 +#define TMR_TMR16B1MR1 (*(pREG32 (0x4001001C))) // Match register 1 +#define TMR_TMR16B1MR2 (*(pREG32 (0x40010020))) // Match register 2 +#define TMR_TMR16B1MR3 (*(pREG32 (0x40010024))) // Match register 3 +#define TMR_TMR16B1CCR (*(pREG32 (0x40010028))) // Capture control register +#define TMR_TMR16B1CR0 (*(pREG32 (0x4001002C))) // Capture register +#define TMR_TMR16B1EMR (*(pREG32 (0x4001003C))) // External match register +#define TMR_TMR16B1CTCR (*(pREG32 (0x40010070))) // Count control register +#define TMR_TMR16B1PWMC (*(pREG32 (0x40010074))) // PWM control register + +#define TMR_TMR16B1IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR16B1IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR16B1IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR16B1IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR16B1IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR16B1IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR16B1IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR16B1IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR16B1IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR16B1IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR16B1IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR16B1TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR16B1TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B1TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR16B1MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR16B1MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR16B1MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR16B1MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B1MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR16B1MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B1MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR16B1MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR16B1MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR16B1MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR16B1MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR16B1MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR16B1MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR16B1MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR16B1MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR16B1MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR16B1MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR16B1MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR16B1MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR16B1MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR16B1MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR16B1MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR16B1MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B1CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR16B1CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR16B1CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR16B1CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B1CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B1EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR16B1EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR16B1EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR16B1EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR16B1EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR16B1EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR16B1EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR16B1EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR16B1EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR16B1EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR16B1EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR16B1EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR16B1EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR16B1EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR16B1EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR16B1EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR16B1EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR16B1EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR16B1EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR16B1EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR16B1EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR16B1EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR16B1EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR16B1EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR16B1CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR16B1CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR16B1CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR16B1CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR16B1CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR16B1CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR16B1CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR16B1PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR16B1PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT16Bn_MAT0 +#define TMR_TMR16B1PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B1PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT16Bn_MAT1 +#define TMR_TMR16B1PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR16B1PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT16Bn_MAT2 +#define TMR_TMR16B1PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR16B1PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B1PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +/*############################################################################## +## 32-Bit Timers (CT32B0/1) +##############################################################################*/ + +#define TMR_CT32B0_BASE_ADDRESS (0x40014000) + +#define TMR_TMR32B0IR (*(pREG32 (0x40014000))) // Interrupt register +#define TMR_TMR32B0TCR (*(pREG32 (0x40014004))) // Timer control register +#define TMR_TMR32B0TC (*(pREG32 (0x40014008))) // Timer counter +#define TMR_TMR32B0PR (*(pREG32 (0x4001400C))) // Prescale register +#define TMR_TMR32B0PC (*(pREG32 (0x40014010))) // Prescale counter register +#define TMR_TMR32B0MCR (*(pREG32 (0x40014014))) // Match control register +#define TMR_TMR32B0MR0 (*(pREG32 (0x40014018))) // Match register 0 +#define TMR_TMR32B0MR1 (*(pREG32 (0x4001401C))) // Match register 1 +#define TMR_TMR32B0MR2 (*(pREG32 (0x40014020))) // Match register 2 +#define TMR_TMR32B0MR3 (*(pREG32 (0x40014024))) // Match register 3 +#define TMR_TMR32B0CCR (*(pREG32 (0x40014028))) // Capture control register +#define TMR_TMR32B0CR0 (*(pREG32 (0x4001402C))) // Capture register +#define TMR_TMR32B0EMR (*(pREG32 (0x4001403C))) // External match register +#define TMR_TMR32B0CTCR (*(pREG32 (0x40014070))) // Count control register +#define TMR_TMR32B0PWMC (*(pREG32 (0x40014074))) // PWM control register + +#define TMR_TMR32B0IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR32B0IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR32B0IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR32B0IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR32B0IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR32B0IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR32B0IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR32B0IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR32B0IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR32B0IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR32B0IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR32B0TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR32B0TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B0TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR32B0MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR32B0MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR32B0MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR32B0MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B0MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR32B0MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR32B0MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR32B0MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR32B0MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR32B0MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR32B0MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR32B0MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR32B0MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR32B0MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR32B0MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR32B0MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR32B0MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR32B0MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR32B0MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR32B0MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR32B0MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR32B0MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR32B0MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B0CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR32B0CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR32B0CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR32B0CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B0CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B0EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR32B0EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR32B0EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR32B0EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR32B0EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR32B0EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR32B0EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR32B0EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR32B0EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR32B0EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR32B0EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR32B0EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR32B0EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR32B0EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR32B0EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR32B0EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR32B0EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR32B0EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR32B0EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR32B0EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR32B0EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR32B0EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR32B0EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR32B0EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR32B0CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR32B0CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR32B0CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR32B0CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR32B0CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR32B0CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR32B0CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR32B0PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR32B0PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT32Bn_MAT0 +#define TMR_TMR32B0PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B0PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT32Bn_MAT1 +#define TMR_TMR32B0PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR32B0PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT32Bn_MAT2 +#define TMR_TMR32B0PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR32B0PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) // PWM mode is enabled for CT32Bn_MAT3 +#define TMR_TMR32B0PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +#define TMR_CT32B1_BASE_ADDRESS (0x40018000) + +#define TMR_TMR32B1IR (*(pREG32 (0x40018000))) // Interrupt register +#define TMR_TMR32B1TCR (*(pREG32 (0x40018004))) // Timer control register +#define TMR_TMR32B1TC (*(pREG32 (0x40018008))) // Timer counter +#define TMR_TMR32B1PR (*(pREG32 (0x4001800C))) // Prescale register +#define TMR_TMR32B1PC (*(pREG32 (0x40018010))) // Prescale counter register +#define TMR_TMR32B1MCR (*(pREG32 (0x40018014))) // Match control register +#define TMR_TMR32B1MR0 (*(pREG32 (0x40018018))) // Match register 0 +#define TMR_TMR32B1MR1 (*(pREG32 (0x4001801C))) // Match register 1 +#define TMR_TMR32B1MR2 (*(pREG32 (0x40018020))) // Match register 2 +#define TMR_TMR32B1MR3 (*(pREG32 (0x40018024))) // Match register 3 +#define TMR_TMR32B1CCR (*(pREG32 (0x40018028))) // Capture control register +#define TMR_TMR32B1CR0 (*(pREG32 (0x4001802C))) // Capture register +#define TMR_TMR32B1EMR (*(pREG32 (0x4001803C))) // External match register +#define TMR_TMR32B1CTCR (*(pREG32 (0x40018070))) // Count control register +#define TMR_TMR32B1PWMC (*(pREG32 (0x40018074))) // PWM control register + +#define TMR_TMR32B1IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR32B1IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR32B1IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR32B1IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR32B1IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR32B1IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR32B1IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR32B1IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR32B1IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR32B1IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR32B1IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR32B1TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR32B1TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B1TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR32B1MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR32B1MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR32B1MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR32B1MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B1MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR32B1MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR32B1MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR32B1MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR32B1MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR32B1MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR32B1MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR32B1MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR32B1MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR32B1MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR32B1MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR32B1MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR32B1MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR32B1MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR32B1MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR32B1MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR32B1MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR32B1MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR32B1MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B1CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR32B1CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR32B1CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR32B1CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B1CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B1EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR32B1EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR32B1EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR32B1EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR32B1EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR32B1EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR32B1EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR32B1EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR32B1EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR32B1EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR32B1EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR32B1EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR32B1EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR32B1EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR32B1EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR32B1EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR32B1EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR32B1EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR32B1EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR32B1EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR32B1EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR32B1EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR32B1EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR32B1EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR32B1CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR32B1CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR32B1CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR32B1CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR32B1CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR32B1CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR32B1CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR32B1PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR32B1PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT32Bn_MAT0 +#define TMR_TMR32B1PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B1PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT32Bn_MAT1 +#define TMR_TMR32B1PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR32B1PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT32Bn_MAT2 +#define TMR_TMR32B1PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR32B1PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) // PWM mode is enabled for CT32Bn_MAT3 +#define TMR_TMR32B1PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +/*############################################################################## +## System Tick Timer +##############################################################################*/ + +#define SYSTICK_BASE_ADDRESS (0xE000E000) + +#define SYSTICK_STCTRL (*(pREG32 (0xE000E010))) // System tick control +#define SYSTICK_STRELOAD (*(pREG32 (0xE000E014))) // System timer reload +#define SYSTICK_STCURR (*(pREG32 (0xE000E018))) // System timer current +#define SYSTICK_STCALIB (*(pREG32 (0xE000E01C))) // System timer calibration + +/* STCTRL (System Timer Control and status register) + The STCTRL register contains control information for the System Tick Timer, and provides + a status flag. */ + +#define SYSTICK_STCTRL_ENABLE (0x00000001) // System tick counter enable +#define SYSTICK_STCTRL_TICKINT (0x00000002) // System tick interrupt enable +#define SYSTICK_STCTRL_CLKSOURCE (0x00000004) // NOTE: This isn't documented but is based on NXP examples +#define SYSTICK_STCTRL_COUNTFLAG (0x00010000) // System tick counter flag + +/* STRELOAD (System Timer Reload value register) + The STRELOAD register is set to the value that will be loaded into the System Tick Timer + whenever it counts down to zero. This register is loaded by software as part of timer + initialization. The STCALIB register may be read and used as the value for STRELOAD if + the CPU or external clock is running at the frequency intended for use with the STCALIB + value. */ + +#define SYSTICK_STRELOAD_MASK (0x00FFFFFF) + +/* STCURR (System Timer Current value register) + The STCURR register returns the current count from the System Tick counter when it is + read by software. */ + +#define SYSTICK_STCURR_MASK (0x00FFFFFF) + +/* STCALIB (System Timer Calibration value register) */ + +#define SYSTICK_STCALIB_TENMS_MASK (0x00FFFFFF) +#define SYSTICK_STCALIB_SKEW_MASK (0x40000000) +#define SYSTICK_STCALIB_NOREF_MASK (0x80000000) + +/*############################################################################## +## ADC +##############################################################################*/ + +#define ADC_AD0_BASE_ADDRESS (0x4001C000) + +#define ADC_AD0CR (*(pREG32 (0x4001C000))) // ADC Control Register +#define ADC_AD0GDR ((unsigned int) 0x4001C004) // ADC Global Data Register +#define ADC_AD0INTEN ((unsigned int) 0x4001C00C) // ADC Interrupt Enable Register +#define ADC_AD0DR0 ((unsigned int) 0x4001C010) // ADC Data Register 0 +#define ADC_AD0DR1 ((unsigned int) 0x4001C014) // ADC Data Register 1 +#define ADC_AD0DR2 ((unsigned int) 0x4001C018) // ADC Data Register 2 +#define ADC_AD0DR3 ((unsigned int) 0x4001C01C) // ADC Data Register 3 +#define ADC_AD0DR4 ((unsigned int) 0x4001C020) // ADC Data Register 4 +#define ADC_AD0DR5 ((unsigned int) 0x4001C024) // ADC Data Register 5 +#define ADC_AD0DR6 ((unsigned int) 0x4001C028) // ADC Data Register 6 +#define ADC_AD0DR7 ((unsigned int) 0x4001C02C) // ADC Data Register 7 +#define ADC_AD0STAT ((unsigned int) 0x4001C030) // ADC Status Register + +#define ADC_AD0CR_SEL_MASK (0x000000FF) +#define ADC_AD0CR_SEL_AD0 (0x00000001) +#define ADC_AD0CR_SEL_AD1 (0x00000002) +#define ADC_AD0CR_SEL_AD2 (0x00000004) +#define ADC_AD0CR_SEL_AD3 (0x00000008) +#define ADC_AD0CR_SEL_AD4 (0x00000010) +#define ADC_AD0CR_SEL_AD5 (0x00000020) +#define ADC_AD0CR_SEL_AD6 (0x00000040) +#define ADC_AD0CR_SEL_AD7 (0x00000080) +#define ADC_AD0CR_CLKDIV_MASK (0x0000FF00) +#define ADC_AD0CR_BURST_MASK (0x00010000) +#define ADC_AD0CR_BURST_SWMODE (0x00000000) +#define ADC_AD0CR_BURST_HWSCANMODE (0x00010000) +#define ADC_AD0CR_CLKS_MASK (0x000E0000) +#define ADC_AD0CR_CLKS_10BITS (0x00000000) +#define ADC_AD0CR_CLKS_9BITS (0x00020000) +#define ADC_AD0CR_CLKS_8BITS (0x00040000) +#define ADC_AD0CR_CLKS_7BITS (0x00060000) +#define ADC_AD0CR_CLKS_6BITS (0x00080000) +#define ADC_AD0CR_CLKS_5BITS (0x000A0000) +#define ADC_AD0CR_CLKS_4BITS (0x000C0000) +#define ADC_AD0CR_CLKS_3BITS (0x000E0000) +#define ADC_AD0CR_START_MASK (0x07000000) +#define ADC_AD0CR_START_NOSTART (0x00000000) +#define ADC_AD0CR_START_STARTNOW (0x01000000) +#define ADC_AD0CR_EDGE_MASK (0x08000000) +#define ADC_AD0CR_EDGE_FALLING (0x08000000) +#define ADC_AD0CR_EDGE_RISING (0x00000000) + +/* AD9GDR (A/D Global Data Register) + The A/D Global Data Register contains the result of the most recent A/D conversion. This + includes the data, DONE, and Overrun flags, and the number of the A/D channel to which + the data relates. */ + +#define ADC_AD0GDR_RESULT_MASK (0x0000FFC0) +#define ADC_AD0GDR_CHN_MASK (0x07000000) // Channel from which the results were converted +#define ADC_AD0GDR_OVERUN_MASK (0x40000000) +#define ADC_AD0GDR_OVERUN (0x40000000) +#define ADC_AD0GDR_DONE_MASK (0x80000000) +#define ADC_AD0GDR_DONE (0x80000000) + +/* AD0STAT (A/D Status Register) + The A/D Status register allows checking the status of all A/D channels simultaneously. + The DONE and OVERRUN flags appearing in the ADDRn register for each A/D channel + are mirrored in ADSTAT. The interrupt flag (the logical OR of all DONE flags) is also found + in ADSTAT. */ + +#define ADC_AD0STAT_DONE0_MASK (0x00000001) +#define ADC_AD0STAT_DONE0 (0x00000001) +#define ADC_AD0STAT_DONE1_MASK (0x00000002) +#define ADC_AD0STAT_DONE1 (0x00000002) +#define ADC_AD0STAT_DONE2_MASK (0x00000004) +#define ADC_AD0STAT_DONE2 (0x00000004) +#define ADC_AD0STAT_DONE3_MASK (0x00000008) +#define ADC_AD0STAT_DONE3 (0x00000008) +#define ADC_AD0STAT_DONE4_MASK (0x00000010) +#define ADC_AD0STAT_DONE4 (0x00000010) +#define ADC_AD0STAT_DONE5_MASK (0x00000020) +#define ADC_AD0STAT_DONE5 (0x00000020) +#define ADC_AD0STAT_DONE6_MASK (0x00000040) +#define ADC_AD0STAT_DONE6 (0x00000040) +#define ADC_AD0STAT_DONE7_MASK (0x00000080) +#define ADC_AD0STAT_DONE7 (0x00000080) +#define ADC_AD0STAT_OVERRUN0_MASK (0x00000100) +#define ADC_AD0STAT_OVERRUN0 (0x00000100) +#define ADC_AD0STAT_OVERRUN1_MASK (0x00000200) +#define ADC_AD0STAT_OVERRUN1 (0x00000200) +#define ADC_AD0STAT_OVERRUN2_MASK (0x00000400) +#define ADC_AD0STAT_OVERRUN2 (0x00000400) +#define ADC_AD0STAT_OVERRUN3_MASK (0x00000800) +#define ADC_AD0STAT_OVERRUN3 (0x00000800) +#define ADC_AD0STAT_OVERRUN4_MASK (0x00001000) +#define ADC_AD0STAT_OVERRUN4 (0x00001000) +#define ADC_AD0STAT_OVERRUN5_MASK (0x00002000) +#define ADC_AD0STAT_OVERRUN5 (0x00002000) +#define ADC_AD0STAT_OVERRUN6_MASK (0x00004000) +#define ADC_AD0STAT_OVERRUN6 (0x00004000) +#define ADC_AD0STAT_OVERRUN7_MASK (0x00008000) +#define ADC_AD0STAT_OVERRUN7 (0x00008000) +#define ADC_AD0STAT_ADINT_MASK (0x00010000) +#define ADC_AD0STAT_ADINT (0x00010000) + +/* ADINTEN0 (A/D Interrupt Enable Register) + This register allows control over which A/D channels generate an interrupt when a + conversion is complete. For example, it may be desirable to use some A/D channels to + monitor sensors by continuously performing conversions on them. The most recent + results are read by the application program whenever they are needed. In this case, an + interrupt is not desirable at the end of each conversion for some A/D channels. */ + +#define ADC_AD0INTEN_ADINTEN0_MASK (0x00000001) +#define ADC_AD0INTEN_ADINTEN0 (0x00000001) +#define ADC_AD0INTEN_ADINTEN1_MASK (0x00000002) +#define ADC_AD0INTEN_ADINTEN1 (0x00000002) +#define ADC_AD0INTEN_ADINTEN2_MASK (0x00000004) +#define ADC_AD0INTEN_ADINTEN2 (0x00000004) +#define ADC_AD0INTEN_ADINTEN3_MASK (0x00000008) +#define ADC_AD0INTEN_ADINTEN3 (0x00000008) +#define ADC_AD0INTEN_ADINTEN4_MASK (0x00000010) +#define ADC_AD0INTEN_ADINTEN4 (0x00000010) +#define ADC_AD0INTEN_ADINTEN5_MASK (0x00000020) +#define ADC_AD0INTEN_ADINTEN5 (0x00000020) +#define ADC_AD0INTEN_ADINTEN6_MASK (0x00000040) +#define ADC_AD0INTEN_ADINTEN6 (0x00000040) +#define ADC_AD0INTEN_ADINTEN7_MASK (0x00000080) +#define ADC_AD0INTEN_ADINTEN7 (0x00000080) +#define ADC_AD0INTEN_ADGINTEN_MASK (0x00000100) +#define ADC_AD0INTEN_ADGINTEN_ENABLE (0x00000100) +#define ADC_AD0INTEN_ADGINTEN_DISABLE (0x00000000) + +/* AD0DR0..7 (A/D Data Registers) + The A/D Data Register hold the result when an A/D conversion is complete, and also + include the flags that indicate when a conversion has been completed and when a + conversion overrun has occurred. */ + +#define ADC_DR_V_MASK (0x0000FFC0) +#define ADC_DR_OVERRUN_MASK (0x40000000) +#define ADC_DR_OVERRUN (0x40000000) +#define ADC_DR_DONE_MASK (0x80000000) +#define ADC_DR_DONE (0x80000000) + +/*############################################################################## +## WDT - Watchdog Timer +##############################################################################*/ + +#define WDT_BASE_ADDRESS (0x40004000) + +#define WDT_WDMOD (*(pREG32 (0x40004000))) // Watchdog mode register +#define WDT_WDTC (*(pREG32 (0x40004004))) // Watchdog timer constant register +#define WDT_WDFEED (*(pREG32 (0x40004008))) // Watchdog feed sequence register +#define WDT_WDTV (*(pREG32 (0x4000400C))) // Watchdog timer value register + +/* WDMOD (Watchdog Mode register) + The WDMOD register controls the operation of the Watchdog through the combination of + WDEN and RESET bits. Note that a watchdog feed must be performed before any + changes to the WDMOD register take effect. */ + +#define WDT_WDMOD_WDEN_DISABLED (0x00000000) // Watchdog enable bit +#define WDT_WDMOD_WDEN_ENABLED (0x00000001) +#define WDT_WDMOD_WDEN_MASK (0x00000001) +#define WDT_WDMOD_WDRESET_DISABLED (0x00000000) // Watchdog reset enable bit +#define WDT_WDMOD_WDRESET_ENABLED (0x00000002) +#define WDT_WDMOD_WDRESET_MASK (0x00000002) +#define WDT_WDMOD_WDTOF (0x00000004) // Watchdog time-out interrupt flag +#define WDT_WDMOD_WDTOF_MASK (0x00000004) // Set when the watchdog times out +#define WDT_WDMOD_WDINT (0x00000008) // Watchdog timer interrupt flag +#define WDT_WDMOD_WDINT_MASK (0x00000008) + +/* WDFEED (Watchdog Feed register) + Writing 0xAA followed by 0x55 to this register will reload the Watchdog timer with the + WDTC value. This operation will also start the Watchdog if it is enabled via the WDMOD + register. Setting the WDEN bit in the WDMOD register is not sufficient to enable the + Watchdog. A valid feed sequence must be completed after setting WDEN before the + Watchdog is capable of generating a reset. Until then, the Watchdog will ignore feed + errors. After writing 0xAA to WDFEED, access to any Watchdog register other than writing + 0x55 to WDFEED causes an immediate reset/interrupt when the Watchdog is enabled. + The reset will be generated during the second PCLK following an incorrect access to a + Watchdog register during a feed sequence. + Interrupts should be disabled during the feed sequence. An abort condition will occur if an + interrupt happens during the feed sequence. */ + +#define WDT_WDFEED_FEED1 (0x000000AA) +#define WDT_WDFEED_FEED2 (0x00000055) + +/*############################################################################## +## Misc. Inline Functions +##############################################################################*/ + +/**************************************************************************/ +/*! + @brief Reverses the bit order of a 32-bit value + + Allows single-cycle reversing of 32-bit values (ASM RBIT) + + @param[in] value + The 32-bit value to reverse + @returns The reversed value +*/ +/**************************************************************************/ +static inline uint32_t RBIT(uint32_t value) { uint32_t result=0; __asm volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); return(result); } + +/**************************************************************************/ +/*! + @brief Causes a system reset and enters the USB Bootloader + + Resets the system using the AIRCR register, and waits in a loop until + reset occurs. The resistor/divider on the LPC1343 Reference Design + Base Board [1] causes the AIRCR reset to enter the bootloader rather + than executing the existing firmware. If you wish to reset and execute + the existing firmware, you need to use the watchdog timer to reset + (see "wdt/wdt.c"). + + [1] http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign.aspx +*/ +/**************************************************************************/ +static inline void __resetBootloader() { __disable_irq(); SCB_AIRCR = SCB_AIRCR_VECTKEY_VALUE | SCB_AIRCR_SYSRESETREQ; while(1); } + +#endif diff --git a/core/pmu/pmu.c b/core/pmu/pmu.c new file mode 100644 index 0000000..e362a51 --- /dev/null +++ b/core/pmu/pmu.c @@ -0,0 +1,419 @@ +/**************************************************************************/ +/*! + @file pmu.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the power management features of the LPC1343, allowing you + to enter sleep/deep-sleep or deep power-down mode. + + For examples of how to enter either mode, see the comments for the + functions pmuSleep(), pmuDeepSleep() and pmuPowerDown(). + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "core/gpio/gpio.h" +#include "core/cpu/cpu.h" +#include "core/timer32/timer32.h" +#include "pmu.h" + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb_drvr.h" +#endif +#define PMU_WDTCLOCKSPEED_HZ 7812 + +void pmuSetupHW(void); +void pmuRestoreHW(void); + + +/**************************************************************************/ +/*! + Wakeup interrupt handler +*/ +/**************************************************************************/ +void WAKEUP_IRQHandler(void) +{ + uint32_t regVal; + + // Reconfigure system clock/PLL + cpuPllSetup(CPU_MULTIPLIER_6); + + // Clear match bit on timer + TMR_TMR32B0EMR = 0; + + // Clear pending bits + SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK; + + // Clear SLEEPDEEP bit + SCB_SCR &= ~SCB_SCR_SLEEPDEEP; + + // Disable the deep sleep timer + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + + /* This handler takes care of all the port pins if they + are configured as wakeup source. */ + regVal = SCB_STARTSRP0; + if (regVal != 0) + { + SCB_STARTRSRP0CLR = regVal; + } + + // Reconfigure CT32B0 + timer32Init(0, TIMER32_DEFAULTINTERVAL); + timer32Enable(0); + + // Perform peripheral specific and custom wakeup tasks + pmuRestoreHW(); + + /* See tracker for bug report. */ + __asm volatile ("NOP"); + + return; +} + +/**************************************************************************/ +/*! + Setup the clock for the watchdog timer. The default is 7.8125kHz. +*/ +/**************************************************************************/ +static void pmuWDTClockInit (void) +{ + /* Enable WDT clock */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC); + + /* Configure watchdog clock */ + /* Freq. = 0.5MHz, div = 64: WDT_OSC = 7.8125kHz */ + SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ | + SCB_WDTOSCCTRL_DIVSEL_DIV64; + + // Switch main clock to WDT output + SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_WDTOSC; + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source + SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; + + // Wait until the clock is updated + while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE)); +} + +/**************************************************************************/ +/*! + @brief Initialises the power management unit +*/ +/**************************************************************************/ +void pmuInit( void ) +{ + /* Enable all clocks, even those turned off at power up. */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC_MASK | + SCB_PDRUNCFG_SYSOSC_MASK | + SCB_PDRUNCFG_ADC_MASK); + + return; +} + +/**************************************************************************/ +/*! + @brief Puts select peripherals in sleep mode. + + This function will put the device into sleep mode. Most gpio pins + can be used to wake the device up, but the pins must first be + configured for this in pmuInit. + + @section Example + + @code + // Configure wakeup sources before going into sleep/deep-sleep. + // By default, pin 0.1 is configured as wakeup source (falling edge) + pmuInit(); + + // Enter sleep mode + pmuSleep(); + @endcode +*/ +/**************************************************************************/ +void pmuSleep() +{ + SCB_PDAWAKECFG = SCB_PDRUNCFG; + __asm volatile ("WFI"); + return; +} + +/**************************************************************************/ +/*! + @brief Turns off select peripherals and puts the device in deep-sleep + mode. + + The device can be configured to wakeup from deep-sleep mode after a + specified delay by supplying a non-zero value to the wakeupSeconds + parameter. This will configure CT32B0 to toggle pin 0.1 (CT32B0_MAT2) + after x seconds, waking the device up. The timer will be configured + to run off the WDT OSC while in deep-sleep mode, meaning that WDTOSC + should not be powered off (using the sleepCtrl parameter) when a + wakeup delay is specified. + + The sleepCtrl parameter is used to indicate which peripherals should + be put in sleep mode (see the SCB_PDSLEEPCFG register for details). + + @param[in] sleepCtrl + The bits to set in the SCB_PDSLEEPCFG register. This + controls which peripherals will be put in sleep mode. + @param[in] wakeupSeconds + The number of seconds to wait until the device will + wakeup. If you do not wish to wakeup after a specific + delay, enter a value of 0. + + @code + uint32_t pmuRegVal; + + // Initialise power management unit + pmuInit(); + + // Put peripherals into sleep mode + pmuRegVal = SCB_PDSLEEPCFG_IRCOUT_PD | + SCB_PDSLEEPCFG_IRC_PD | + SCB_PDSLEEPCFG_FLASH_PD | + SCB_PDSLEEPCFG_USBPLL_PD | + SCB_PDSLEEPCFG_SYSPLL_PD | + SCB_PDSLEEPCFG_SYSOSC_PD | + SCB_PDSLEEPCFG_ADC_PD | + SCB_PDSLEEPCFG_BOD_PD; + + // Enter deep sleep mode (wakeup after 5 seconds) + // By default, pin 0.1 is configured as wakeup source + pmuDeepSleep(pmuRegVal, 5); + @endcode +*/ +/**************************************************************************/ +void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds) +{ + // Setup the board for deep sleep mode, shutting down certain + // peripherals and remapping pins for lower power + pmuSetupHW(); + SCB_PDAWAKECFG = SCB_PDRUNCFG; + sleepCtrl |= (1 << 9) | (1 << 11); + SCB_PDSLEEPCFG = sleepCtrl; + SCB_SCR |= SCB_SCR_SLEEPDEEP; + + /* Configure system to run from WDT and set TMR32B0 for wakeup */ + if (wakeupSeconds > 0) + { + // Make sure WDTOSC isn't disabled in PDSLEEPCFG + SCB_PDSLEEPCFG &= ~(SCB_PDSLEEPCFG_WDTOSC_PD); + + // Disable 32-bit timer 0 if currently in use + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + + // Disable internal pullup on 0.1 + gpioSetPullup(&IOCON_PIO0_1, gpioPullupMode_Inactive); + + /* Enable the clock for CT32B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); + + /* Configure 0.1 as Timer0_32 MAT2 */ + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2; + + /* Set appropriate timer delay */ + TMR_TMR32B0MR0 = PMU_WDTCLOCKSPEED_HZ * wakeupSeconds; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B0MCR |= (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED); + + /* Configure external match register to set 0.1 high on match */ + TMR_TMR32B0EMR &= ~(0xFF<<4); // Clear EMR config bits + TMR_TMR32B0EMR |= TMR_TMR32B0EMR_EMC2_HIGH; // Set MAT2 (0.1) high on match + + /* Enable wakeup interrupts (any I/O pin can be used as a wakeup source) */ + //NVIC_EnableIRQ(WAKEUP0_IRQn); // P0.0 + NVIC_EnableIRQ(WAKEUP1_IRQn); // P0.1 (CT32B0_MAT2) + //NVIC_EnableIRQ(WAKEUP2_IRQn); // P0.2 + //NVIC_EnableIRQ(WAKEUP3_IRQn); // P0.3 + //NVIC_EnableIRQ(WAKEUP4_IRQn); // P0.4 + //NVIC_EnableIRQ(WAKEUP5_IRQn); // P0.5 + //NVIC_EnableIRQ(WAKEUP6_IRQn); // P0.6 + //NVIC_EnableIRQ(WAKEUP7_IRQn); // P0.7 + //NVIC_EnableIRQ(WAKEUP8_IRQn); // P0.8 + //NVIC_EnableIRQ(WAKEUP9_IRQn); // P0.9 + //NVIC_EnableIRQ(WAKEUP10_IRQn); // P0.10 + //NVIC_EnableIRQ(WAKEUP11_IRQn); // P0.11 + //NVIC_EnableIRQ(WAKEUP12_IRQn); // P1.0 + //NVIC_EnableIRQ(WAKEUP13_IRQn); // P1.1 + //NVIC_EnableIRQ(WAKEUP14_IRQn); // P1.2 + //NVIC_EnableIRQ(WAKEUP15_IRQn); // P1.3 + //NVIC_EnableIRQ(WAKEUP16_IRQn); // P1.4 + //NVIC_EnableIRQ(WAKEUP17_IRQn); // P1.5 + //NVIC_EnableIRQ(WAKEUP18_IRQn); // P1.6 + //NVIC_EnableIRQ(WAKEUP19_IRQn); // P1.7 + //NVIC_EnableIRQ(WAKEUP20_IRQn); // P1.8 + //NVIC_EnableIRQ(WAKEUP21_IRQn); // P1.9 + //NVIC_EnableIRQ(WAKEUP22_IRQn); // P1.10 + //NVIC_EnableIRQ(WAKEUP23_IRQn); // P1.11 + //NVIC_EnableIRQ(WAKEUP24_IRQn); // P2.0 + //NVIC_EnableIRQ(WAKEUP25_IRQn); // P2.1 + //NVIC_EnableIRQ(WAKEUP26_IRQn); // P2.2 + //NVIC_EnableIRQ(WAKEUP27_IRQn); // P2.3 + //NVIC_EnableIRQ(WAKEUP28_IRQn); // P2.4 + //NVIC_EnableIRQ(WAKEUP29_IRQn); // P2.5 + //NVIC_EnableIRQ(WAKEUP30_IRQn); // P2.6 + //NVIC_EnableIRQ(WAKEUP31_IRQn); // P2.7 + //NVIC_EnableIRQ(WAKEUP32_IRQn); // P2.8 + //NVIC_EnableIRQ(WAKEUP33_IRQn); // P2.9 + //NVIC_EnableIRQ(WAKEUP34_IRQn); // P2.10 + //NVIC_EnableIRQ(WAKEUP35_IRQn); // P2.11 + //NVIC_EnableIRQ(WAKEUP36_IRQn); // P3.0 + //NVIC_EnableIRQ(WAKEUP37_IRQn); // P3.1 + //NVIC_EnableIRQ(WAKEUP38_IRQn); // P3.2 + //NVIC_EnableIRQ(WAKEUP39_IRQn); // P3.3 + + /* Use RISING EDGE for wakeup detection. */ + SCB_STARTAPRP0 |= SCB_STARTAPRP0_APRPIO0_1; + + /* Clear all wakeup sources */ + SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK; + + /* Enable Port 0.1 as wakeup source. */ + SCB_STARTERP0 |= SCB_STARTERP0_ERPIO0_1; + + // Reconfigure clock to run from WDTOSC + pmuWDTClockInit(); + + /* Start the timer */ + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED; + } + + __asm volatile ("WFI"); + return; +} + +/**************************************************************************/ +/*! + @brief Puts the device in deep power-down mode. + + This function will configure the PMU control register and enter + deep power-down mode. Pre-determined values are stored in the four + general-purpose registers (PMU_GPREG0..3), which can be used to persist + any essential system settings while the device is in deep power-down + mode, so long as 3.3V is still available. + + @warning The only way to wake a device up from deep power-down mode + is to set a low-level on P1.4. If 3.3V power is lost, the + values stored in the four general-purpose registers will + also be lost. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/pmu/pmu.h" + + int main(void) + { + cpuInit(); + pmuInit(); + + // Enter power-down mode + pmuPowerDown(); + + while(1) + { + // Device was woken up by WAKEUP pin + } + } + @endcode +*/ +/**************************************************************************/ +void pmuPowerDown( void ) +{ + uint32_t regVal; + + // Make sure HW and external devices are in low power mode + pmuSetupHW(); + + if ( (PMU_PMUCTRL & ((0x1<<8) | (PMU_PMUCTRL_DPDFLAG))) != 0x0 ) + { + /* Check sleep and deep power down bits. If sleep and/or + deep power down mode are entered, clear the PCON bits. */ + regVal = PMU_PMUCTRL; + regVal |= ((0x1<<8) | + (PMU_PMUCTRL_DPDEN_SLEEP) | + (PMU_PMUCTRL_DPDFLAG)); + PMU_PMUCTRL = regVal; + + if ( (PMU_GPREG0 != 0x12345678)||(PMU_GPREG1 != 0x87654321) + ||(PMU_GPREG2 != 0x56781234)||(PMU_GPREG3 != 0x43218765) ) + { + while (1); + } + } + else + { + /* If in neither sleep nor deep-sleep mode, enter deep power down mode. */ + PMU_GPREG0 = 0x12345678; + PMU_GPREG1 = 0x87654321; + PMU_GPREG2 = 0x56781234; + PMU_GPREG3 = 0x43218765; + SCB_SCR |= SCB_SCR_SLEEPDEEP; + PMU_PMUCTRL = PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN; + __asm volatile ("WFI"); + } + return; +} + +/**************************************************************************/ +/*! + @brief Configures parts and system peripherals to use lower power + before entering sleep mode +*/ +/**************************************************************************/ +void pmuSetupHW(void) +{ + #ifdef CFG_CHIBI + chb_sleep(TRUE); + #endif +} + +/**************************************************************************/ +/*! + @brief Restores parts and system peripherals to an appropriate + state after waking up from deep-sleep mode +*/ +/**************************************************************************/ +void pmuRestoreHW(void) +{ + #ifdef CFG_CHIBI + // Wakeup Chibi/Transceiver + chb_sleep(FALSE); + #endif +} diff --git a/core/pmu/pmu.h b/core/pmu/pmu.h new file mode 100644 index 0000000..e5b45fb --- /dev/null +++ b/core/pmu/pmu.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file pmu.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __PMU_H__ +#define __PMU_H__ + +#include "projectconfig.h" + +void WAKEUP_IRQHandler( void ); +void pmuInit( void ); +void pmuSleep( void ); +void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds); +void pmuPowerDown( void ); + +#endif diff --git a/core/projectconfig.h b/core/projectconfig.h new file mode 100644 index 0000000..3edc787 --- /dev/null +++ b/core/projectconfig.h @@ -0,0 +1,58 @@ +#include "lpc134x.h" +#include "sysdefs.h" + + + +/*========================================================================= + CORE CPU SETTINGS + ----------------------------------------------------------------------- + + CFG_CPU_CCLK Value is for reference only. 'core/cpu/cpu.c' must + be modified to change the clock speed, but the value + should be indicated here since CFG_CPU_CCLK is used by + other peripherals to determine timing. + + -----------------------------------------------------------------------*/ + #define CFG_CPU_CCLK (72000000) // 1 tick = 13.88nS +/*=========================================================================*/ + + +/*========================================================================= + SYSTICK TIMER + ----------------------------------------------------------------------- + + CFG_SYSTICK_DELAY_IN_MS The number of milliseconds between each tick + of the systick timer. + + -----------------------------------------------------------------------*/ + #define CFG_SYSTICK_DELAY_IN_MS (1) +/*=========================================================================*/ + + +/*========================================================================= + SSP + ----------------------------------------------------------------------- + + CFG_SSP0_SCKPIN_2_11 Indicates which pin should be used for SCK0 + CFG_SSP0_SCKPIN_0_6 + + -----------------------------------------------------------------------*/ + #define CFG_SSP0_SCKPIN_2_11 +/*=========================================================================*/ + +/*========================================================================= + ON-BOARD LED + ----------------------------------------------------------------------- + + CFG_LED_PORT The port for the on board LED + CFG_LED_PIN The pin for the on board LED + CFG_LED_ON The pin state to turn the LED on (0 = low, 1 = high) + CFG_LED_OFF The pin state to turn the LED off (0 = low, 1 = high) + + -----------------------------------------------------------------------*/ + #define CFG_LED_PORT (1) + #define CFG_LED_PIN (11) + #define CFG_LED_ON (1) + #define CFG_LED_OFF (0) + +/*=========================================================================*/ diff --git a/core/pwm/pwm.c b/core/pwm/pwm.c new file mode 100644 index 0000000..3049b6b --- /dev/null +++ b/core/pwm/pwm.c @@ -0,0 +1,254 @@ +/**************************************************************************/ +/*! + @file pwm.c + @author K. Townsend (microBuilder.eu) + + @brief Simple PWM example that can be used to control a motor, dim + an LED, etc. Uses 16-bit Timer 1 and P1.9 for PWM output. + + @section Example + + @code + #include "core/pwm/pwm.h" + ... + + // Initialises PWM output on 16-bit Timer 1 and + // sets MAT0 (P1.9) as output + pwmInit(); + + // Setup the pulse-width and duty-cycle + pwmSetDutyCycle(50); // Set 50% duty cycle + pwmSetFrequencyInMicroseconds(100); // 100 millisecond pulse width + + // Enable PWM output for exactly 50 pulses + pwmStartFixed(50); + + // Alternatively, enable PWM output indefinately + pwmStart(); + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "pwm.h" + +uint32_t pwmPulseWidth = CFG_PWM_DEFAULT_PULSEWIDTH; +uint32_t pwmDutyCycle = CFG_PWM_DEFAULT_DUTYCYCLE; + +// pwmMaxPulses is used by TIMER16_1_IRQHandler to turn PWM off after +// a specified number of pulses have been sent. This only relevant when +// pwmStartFixed() is used. +volatile uint32_t pwmMaxPulses = 0; + +/**************************************************************************/ +/*! + Initialises 16-bit Timer 1, and configures the MAT0 output (pin 1.9) + to send the PWM output signal. +*/ +/**************************************************************************/ +void pwmInit(void) +{ + /* Enable the clock for CT16B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1); + + /* Configure PIO1.9 as Timer1_16 MAT0 Output */ + /* Alternatively, PIO1.10 (MAT1) can also be used though + the initialisation code will need to be modified */ + IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK; + IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0; + + /* Set default pulse width (MR3)*/ + TMR_TMR16B1MR3 = pwmPulseWidth; + + /* Set default duty cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + /* Configure match control register to reset on MR3 */ + TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR3_RESET_ENABLED); + + /* External Match Register Settings for PWM */ + TMR_TMR16B1EMR = TMR_TMR16B1EMR_EMC0_TOGGLE | TMR_TMR16B1EMR_EM0; + + /* Disable Timer1 by default (enabled by pwmStart of pwmStartFixed) */ + TMR_TMR16B1TCR &= ~TMR_TMR16B1TCR_COUNTERENABLE_MASK; + + /* Enable PWM0 and PWM3 */ + TMR_TMR16B1PWMC = TMR_TMR16B1PWMC_PWM0_ENABLED | TMR_TMR16B1PWMC_PWM3_ENABLED; + + /* Make sure that the timer interrupt is enabled */ + NVIC_EnableIRQ(TIMER_16_1_IRQn); +} + +/**************************************************************************/ +/*! + Starts the PWM output +*/ +/**************************************************************************/ +void pwmStart(void) +{ + /* Disable interrupt on MR3 in case it was enabled by pwmStartFixed() */ + TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK); + + /* Enable Timer1 */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; +} + +/**************************************************************************/ +/*! + Stops the PWM output +*/ +/**************************************************************************/ +void pwmStop(void) +{ + /* Disable Timer1 */ + TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK); +} + +/**************************************************************************/ +/*! + Starts the PWM output, and stops after the specified number of + pulses. + + @param[in] pulses + The number of pulses to generate before disabling the + PWM output. The output is actually disabled in the + timer ISR. + + @warning The PWM output is actually stopped inside the 16-bit + timer ISR in "core/timer16/timer16.h". +*/ +/**************************************************************************/ +void pwmStartFixed(uint32_t pulses) +{ + pwmMaxPulses = pulses; + + /* Configure match control register to also raise an interrupt on MR3 */ + TMR_TMR16B1MCR |= (TMR_TMR16B1MCR_MR3_INT_ENABLED); + + /* Enable Timer1 (it will eventually be disabled in the ISR) */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; +} + +/**************************************************************************/ +/*! + Sets the signal's duty cycle in percent (1-100). + + @param[in] percentage + The duty-cycle in percentage (the amount of time that + the signal is 'high' relative to the time its 'low'). + + @returns -1 if an invalid percentage was supplied. Value must be + between 1 and 100. +*/ +/**************************************************************************/ +int pwmSetDutyCycle(uint32_t percentage) +{ + if ((percentage < 1) || (percentage > 100)) + { + /* Duty Cycle must be a value between 1 and 100 */ + return -1; + } + + /* Set Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - (pwmDutyCycle = percentage))) / 100; + + return 0; +} + +/**************************************************************************/ +/*! + Sets the signal's frequency/pulse-width to the specified number + of ticks. + + @param[in] ticks + The duration in clock ticks of each full pulse. + + @returns -1 if a zero-value was provided for ticks. +*/ +/**************************************************************************/ +int pwmSetFrequencyInTicks(uint16_t ticks) +{ + if (ticks < 1) + { + return -1; + } + + /* Set Pulse Width (MR3)*/ + TMR_TMR16B1MR3 = (pwmPulseWidth = ticks); + + /* Adjust Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + return 0; +} + +/**************************************************************************/ +/*! + Sets the signal's frequency/pulse-width to the specified number + of microseconds. + + @param[in] us + The duration in microseconds of each full pulse. + + @returns -1 if the supplied value exceeds the limits of the 16-bit + timer, or if a zero-value was provided. + + @Warning Because a 16-bit timer is used here by default, the + maximum frequency is quite small. Running at 36MHz, the + largest possible pulse-width/frequency is ~1,82mS or + 1820 microSeconds. At 12MHz its 5461 uS, and at 48MHz + its 1365 uS. +*/ +/**************************************************************************/ +int pwmSetFrequencyInMicroseconds(uint16_t us) +{ + if (us < 1) + { + return -1; + } + + uint32_t ticks = (((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000) * us); + if (ticks > 0xFFFF) + { + /* Delay exceeds the upper limit for the 16-bit timer */ + return -1; + } + + /* Set Pulse Width (MR3)*/ + TMR_TMR16B1MR3 = (pwmPulseWidth = ticks); + + /* Adjust Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + return 0; +} + + diff --git a/core/pwm/pwm.h b/core/pwm/pwm.h new file mode 100644 index 0000000..48391a2 --- /dev/null +++ b/core/pwm/pwm.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file pwm.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PWM_H_ +#define _PWM_H_ + +#include "projectconfig.h" + +void pwmInit( void ); +void pwmStart( void ); +void pwmStop( void ); +void pwmStartFixed( uint32_t pulses ); +int pwmSetDutyCycle( uint32_t percentage ); +int pwmSetFrequencyInTicks( uint16_t ticks ); +int pwmSetFrequencyInMicroseconds(uint16_t us ); + +#endif \ No newline at end of file diff --git a/core/rom_drivers.h b/core/rom_drivers.h new file mode 100644 index 0000000..f1c4184 --- /dev/null +++ b/core/rom_drivers.h @@ -0,0 +1,58 @@ +/**************************************************************************/ +/*! + @file rom_drivers.h + @author NXP Semiconductor +*/ +/**************************************************************************/ + +#ifndef ROM_DRIVERS_H_ +#define ROM_DRIVERS_H_ + +#include "sysdefs.h" + +typedef struct _USB_DEVICE_INFO +{ + uint16_t DevType; + uint32_t DevDetailPtr; +} USB_DEV_INFO; + +typedef struct _USBD +{ + void (*init_clk_pins)(void); + void (*isr)(void); + void (*init)( USB_DEV_INFO * DevInfoPtr ); + void (*connect)(uint32_t con); +} USBD; + +typedef struct _ROM +{ + const USBD * pUSBD; +} ROM; + +typedef struct _MSC_DEVICE_INFO { + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint32_t MSCInquiryStr; + uint32_t BlockCount; + uint32_t BlockSize; + uint32_t MemorySize; + void (*MSC_Write)( uint32_t offset, uint8_t src[], uint32_t length); + void (*MSC_Read)( uint32_t offset, uint8_t dst[], uint32_t length); +} MSC_DEVICE_INFO; + +typedef struct _HID_DEVICE_INFO +{ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint8_t InReportCount; + uint8_t OutReportCount; + uint8_t SampleInterval; + void (*InReport)(uint8_t src[], uint32_t length); + void (*OutReport)(uint8_t dst[], uint32_t length); +} HID_DEVICE_INFO; + +#endif diff --git a/core/ssp/ssp.c b/core/ssp/ssp.c new file mode 100644 index 0000000..6fce2e8 --- /dev/null +++ b/core/ssp/ssp.c @@ -0,0 +1,299 @@ +/**************************************************************************/ +/*! + @file ssp.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for SSP/SPI communications. By default, the SSP block + is initialised in SPI master mode. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/ssp/ssp.h" + ... + cpuInit(); + sspInit(0, sspClockPolarity_High, sspClockPhase_RisingEdge); + ... + uint8_t request[SSP_FIFOSIZE]; + uint8_t response[SSP_FIFOSIZE]; + + // Send 0x9C to the slave device and wait for a response + request[0] = 0x80 | 0x1C; + // Toggle the select pin + ssp0Select(); + // Send 1 byte from the request buffer + sspSend(0, (uint8_t *)&request, 1); + // Receive 1 byte into the response buffer + sspReceive(0, (uint8_t *)&response, 1); + // Reset the select pin + ssp0Deselect(); + // Print the results + debug_printf("Ox%x ", response[0]); + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "ssp.h" +#include "core/gpio/gpio.h" + +/* Statistics for all interrupts */ +volatile uint32_t interruptRxStat = 0; +volatile uint32_t interruptOverRunStat = 0; +volatile uint32_t interruptRxTimeoutStat = 0; + +/**************************************************************************/ +/*! + @brief SSP0 interrupt handler for SPI communication + + The algorithm is, if RXFIFO is at least half full, + start receive until it's empty; if TXFIFO is at least + half empty, start transmit until it's full. + This will maximize the use of both FIFOs and performance. +*/ +/**************************************************************************/ +void SSP_IRQHandler (void) +{ + uint32_t regValue; + + regValue = SSP_SSP0MIS; + + /* Check for overrun interrupt */ + if ( regValue & SSP_SSP0MIS_RORMIS_FRMRCVD ) + { + interruptOverRunStat++; + SSP_SSP0ICR = SSP_SSP0ICR_RORIC_CLEAR; // Clear interrupt + } + + /* Check for timeout interrupt */ + if ( regValue & SSP_SSP0MIS_RTMIS_NOTEMPTY ) + { + interruptRxTimeoutStat++; + SSP_SSP0ICR = SSP_SSP0ICR_RTIC_CLEAR; // Clear interrupt + } + + /* Check if Rx buffer is at least half-full */ + if ( regValue & SSP_SSP0MIS_RXMIS_HALFFULL ) + { + // ToDo: Receive until it's empty + interruptRxStat++; + } + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the SSP0 port + + By default, SSP0 is set to SPI frame-format with 8-bit data. Pin 2.11 + is routed to serve as serial clock (SCK), and SSEL (0.2) is set to + GPIO to allow manual control of when the SPI port is enabled or + disabled. Overrun and timeout interrupts are both enabled. + + @param[in] portNum + The SPI port to use (0..1) + @param[in] polarity + Indicates whether the clock should be held high + (sspClockPolarity_High) or low (sspClockPolarity_Low) + when inactive. + @param[in] phase + Indicates whether new bits start on the leading + (sspClockPhase_RisingEdge) or falling + (sspClockPhase_FallingEdge) edge of clock transitions. + + @note sspSelect() and sspDeselect() macros have been defined in + ssp.h to control the SSEL line without having to know the + specific pin being used. +*/ +/**************************************************************************/ +void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase) +{ + gpioInit(); + + if (portNum == 0) + { + /* Reset SSP */ + SCB_PRESETCTRL &= ~SCB_PRESETCTRL_SSP0_MASK; + SCB_PRESETCTRL |= SCB_PRESETCTRL_SSP0_RESETDISABLED; + + /* Enable AHB clock to the SSP domain. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_SSP0); + + /* Divide by 1 (SSPCLKDIV also enables to SSP CLK) */ + SCB_SSP0CLKDIV = SCB_SSP0CLKDIV_DIV1; + + /* Set P0.8 to SSP MISO */ + IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK; + IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_MISO0; + + /* Set P0.9 to SSP MOSI */ + IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK; + IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_MOSI0; + + /* Set 2.11 to SSP SCK (0.6 and 0.10 can also be used) */ + #ifdef CFG_SSP0_SCKPIN_2_11 + IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO2_11; + IOCON_PIO2_11 = IOCON_PIO2_11_FUNC_SCK0; + #endif + + /* Set 0.6 to SSP SCK (2.11 and 0.10 can also be used) */ + #ifdef CFG_SSP0_SCKPIN_0_6 + IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO0_6; + IOCON_PIO0_6 = IOCON_PIO0_6_FUNC_SCK; + #endif + + /* Set P0.2/SSEL to GPIO output and high */ + IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK; + IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_GPIO; + gpioSetDir(SSP0_CSPORT, SSP0_CSPIN, 1); + gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1); + gpioSetPullup(&IOCON_PIO0_2, gpioPullupMode_Inactive); // Board has external pull-up + + /* If SSP0CLKDIV = DIV1 -- (PCLK / (CPSDVSR × [SCR+1])) = (72,000,000 / (2 x [8 + 1])) = 4.0 MHz */ + uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit + | SSP_SSP0CR0_FRF_SPI // Frame format = SPI + | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 + + // Set clock polarity + if (polarity == sspClockPolarity_High) + configReg |= SSP_SSP0CR0_CPOL_HIGH; // Clock polarity = High between frames + else + configReg &= ~SSP_SSP0CR0_CPOL_MASK; // Clock polarity = Low between frames + + // Set edge transition + if (phase == sspClockPhase_FallingEdge) + configReg |= SSP_SSP0CR0_CPHA_SECOND; // Clock out phase = Trailing edge clock transition + else + configReg &= ~SSP_SSP0CR0_CPHA_MASK; // Clock out phase = Leading edge clock transition + + // Assign config values to SSP0CR0 + SSP_SSP0CR0 = configReg; + + /* Clock prescale register must be even and at least 2 in master mode */ + SSP_SSP0CPSR = SSP_SSP0CPSR_CPSDVSR_DIV2; + + /* Clear the Rx FIFO */ + uint8_t i, Dummy=Dummy; + for ( i = 0; i < SSP_FIFOSIZE; i++ ) + { + Dummy = SSP_SSP0DR; + } + + /* Enable the SSP Interrupt */ + NVIC_EnableIRQ(SSP_IRQn); + + /* Set SSPINMS registers to enable interrupts + * enable all error related interrupts */ + SSP_SSP0IMSC = ( SSP_SSP0IMSC_RORIM_ENBL // Enable overrun interrupt + | SSP_SSP0IMSC_RTIM_ENBL); // Enable timeout interrupt + + /* Enable device and set it to master mode, no loopback */ + SSP_SSP0CR1 = SSP_SSP0CR1_SSE_ENABLED | SSP_SSP0CR1_MS_MASTER | SSP_SSP0CR1_LBM_NORMAL; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Sends a block of data to the SSP0 port + + @param[in] portNum + The SPI port to use (0..1) + @param[in] buf + Pointer to the data buffer + @param[in] length + Block length of the data buffer +*/ +/**************************************************************************/ +void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length) +{ + uint32_t i; + uint8_t Dummy = Dummy; + + if (portNum == 0) + { + for (i = 0; i < length; i++) + { + /* Move on only if NOT busy and TX FIFO not full. */ + while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL); + SSP_SSP0DR = *buf; + buf++; + + while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY ); + /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO + on MISO. Otherwise, when SSP0Receive() is called, previous data byte + is left in the FIFO. */ + Dummy = SSP_SSP0DR; + } + } + + return; +} + +/**************************************************************************/ +/*! + @brief Receives a block of data from the SSP0 port + + @param[in] portNum + The SPI port to use (0..1) + @param[in] buf + Pointer to the data buffer + @param[in] length + Block length of the data buffer +*/ +/**************************************************************************/ +void sspReceive(uint8_t portNum, uint8_t *buf, uint32_t length) +{ + uint32_t i; + + if (portNum == 0) + { + for ( i = 0; i < length; i++ ) + { + /* As long as the receive FIFO is not empty, data can be received. */ + SSP_SSP0DR = 0xFF; + + /* Wait until the Busy bit is cleared */ + while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY ); + + *buf = SSP_SSP0DR; + buf++; + } + } + + return; +} + diff --git a/core/ssp/ssp.h b/core/ssp/ssp.h new file mode 100644 index 0000000..19b2ca9 --- /dev/null +++ b/core/ssp/ssp.h @@ -0,0 +1,85 @@ +/**************************************************************************/ +/*! + @file ssp.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SSP_H_ +#define _SSP_H_ + +#include "projectconfig.h" +#include "core/gpio/gpio.h" + +#define SSP_FIFOSIZE 8 /* SPI read and write buffer size */ +#define SSP_MAX_TIMEOUT 0xFF + +#define SSP0_CSPORT 0 +#define SSP0_CSPIN 2 + +/* Macro definitions to enable and disable SPI */ +#define ssp0Select() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 0);} while (0) +#define ssp0Deselect() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1);} while (0) + +/**************************************************************************/ +/*! + Indicates whether the clock should be high or low between frames. +*/ +/**************************************************************************/ +typedef enum sspClockPolarity_e +{ + sspClockPolarity_Low = 0, + sspClockPolarity_High +} +sspClockPolarity_t; + +/**************************************************************************/ +/*! + Indicates whether the bits start at the rising or falling edge of + the clock transition. +*/ +/**************************************************************************/ +typedef enum sspClockPhase_e +{ + sspClockPhase_RisingEdge = 0, + sspClockPhase_FallingEdge +} +sspClockPhase_t; + +extern void SSP_IRQHandler (void); +void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase); +void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length); +void sspReceive (uint8_t portNum, uint8_t *buf, uint32_t length); + +#endif diff --git a/core/sysdefs.h b/core/sysdefs.h new file mode 100644 index 0000000..9c461a0 --- /dev/null +++ b/core/sysdefs.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/*! + @file sysdefs.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SYSDEFS_H_ +#define _SYSDEFS_H_ + +#include +#include +#include + +// Stay compatible with ugly "windows" style +#define BOOL bool +#define TRUE true +#define FALSE false + +typedef volatile uint8_t REG8; +typedef volatile uint16_t REG16; +typedef volatile uint32_t REG32; +typedef unsigned char byte_t; + +#define pREG8 (REG8 *) +#define pREG16 (REG16 *) +#define pREG32 (REG32 *) + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#endif + diff --git a/core/sysinit.c b/core/sysinit.c new file mode 100644 index 0000000..c3acc64 --- /dev/null +++ b/core/sysinit.c @@ -0,0 +1,280 @@ +/**************************************************************************/ +/*! + @file sysinit.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include +#include +#include + +#include "sysinit.h" + +#include "core/cpu/cpu.h" +#include "core/pmu/pmu.h" +#include "core/adc/adc.h" + +#ifdef CFG_PRINTF_UART + #include "core/uart/uart.h" +#endif + +#ifdef CFG_INTERFACE + #include "core/cmd/cmd.h" +#endif + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb.h" +#endif + +#ifdef CFG_USBHID + #include "core/usbhid-rom/usbhid.h" +#endif + +#ifdef CFG_USBCDC + volatile unsigned int lastTick; + #include "core/usbcdc/usb.h" + #include "core/usbcdc/usbcore.h" + #include "core/usbcdc/usbhw.h" + #include "core/usbcdc/cdcuser.h" + #include "core/usbcdc/cdc_buf.h" +#endif + +#ifdef CFG_ST7565 + #include "drivers/lcd/bitmap/st7565/st7565.h" + #include "drivers/lcd/smallfonts.h" +#endif + +#ifdef CFG_SSD1306 + #include "drivers/lcd/bitmap/ssd1306/ssd1306.h" + #include "drivers/lcd/smallfonts.h" +#endif + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/touchscreen.h" + #include "drivers/lcd/tft/drawing.h" +#endif + +#ifdef CFG_I2CEEPROM + #include "drivers/eeprom/mcp24aa/mcp24aa.h" + #include "drivers/eeprom/eeprom.h" +#endif + +#ifdef CFG_PWM + #include "core/pwm/pwm.h" +#endif + +#ifdef CFG_SDCARD + #include "core/ssp/ssp.h" + #include "drivers/fatfs/diskio.h" + #include "drivers/fatfs/ff.h" + + DWORD get_fattime () + { + // ToDo! + return 0; + } +#endif + +/**************************************************************************/ +/*! + Configures the core system clock and sets up any mandatory + peripherals like the systick timer, UART for printf, etc. + + This function should set the HW to the default state you wish to be + in coming out of reset/startup, such as disabling or enabling LEDs, + setting specific pin states, etc. +*/ +/**************************************************************************/ +void systemInit() +{ + cpuInit(); // Configure the CPU + systickInit(CFG_SYSTICK_DELAY_IN_MS); // Start systick timer + gpioInit(); // Enable GPIO + pmuInit(); // Configure power management + adcInit(); // Config adc pins to save power + + // Set LED pin as output and turn LED off + gpioSetDir(CFG_LED_PORT, CFG_LED_PIN, 1); + gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + + // Initialise EEPROM + #ifdef CFG_I2CEEPROM + mcp24aaInit(); + #endif + + // Initialise UART with the default baud rate + #ifdef CFG_PRINTF_UART + uint32_t uart = eepromReadU32(CFG_EEPROM_UART_SPEED); + if ((uart == 0xFFFFFFFF) || (uart > 115200)) + { + uartInit(CFG_UART_BAUDRATE); // Use default baud rate + } + else + { + uartInit(uart); // Use baud rate from EEPROM + } + #endif + + // Initialise PWM (requires 16-bit Timer 1 and P1.9) + #ifdef CFG_PWM + pwmInit(); + #endif + + // Initialise USB HID + #ifdef CFG_USBHID + usbHIDInit(); + #endif + + // Initialise USB CDC + #ifdef CFG_USBCDC + lastTick = systickGetTicks(); // Used to control output/printf timing + CDC_Init(); // Initialise VCOM + USB_Init(); // USB Initialization + USB_Connect(TRUE); // USB Connect + // Wait until USB is configured or timeout occurs + uint32_t usbTimeout = 0; + while ( usbTimeout < CFG_USBCDC_INITTIMEOUT / 10 ) + { + if (USB_Configuration) break; + systickDelay(10); // Wait 10ms + usbTimeout++; + } + #endif + + // Printf can now be used with UART or USBCDC + + // Initialise the ST7565 128x64 pixel display + #ifdef CFG_ST7565 + st7565Init(); + st7565ClearScreen(); // Clear the screen + st7565Backlight(1); // Enable the backlight + #endif + + // Initialise the SSD1306 OLED display + #ifdef CFG_SSD1306 + ssd1306Init(SSD1306_SWITCHCAPVCC); + ssd1306ClearScreen(); // Clear the screen + #endif + + // Initialise TFT LCD Display + #ifdef CFG_TFTLCD + lcdInit(); + #endif + + // Initialise Chibi + // Warning: CFG_CHIBI must be disabled if no antenna is connected, + // otherwise the SW will halt during initialisation + #ifdef CFG_CHIBI + // Write addresses to EEPROM for the first time if necessary + // uint16_t addr_short = 0x0025; + // uint64_t addr_ieee = 0x0000000000000025; + // mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t *)&addr_short, 2); + // mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t *)&addr_ieee, 8); + chb_init(); + // chb_pcb_t *pcb = chb_get_pcb(); + // printf("%-40s : 0x%04X%s", "Chibi Initialised", pcb->src_addr, CFG_PRINTF_NEWLINE); + #endif + + // Start the command line interface + #ifdef CFG_INTERFACE + cmdInit(); + #endif +} + +/**************************************************************************/ +/*! + @brief Sends a single byte to a pre-determined peripheral (UART, etc.). + + @param[in] byte + Byte value to send +*/ +/**************************************************************************/ +void __putchar(const char c) +{ + #ifdef CFG_PRINTF_UART + // Send output to UART + uartSendByte(c); + #endif +} + +#ifdef CFG_USBCDC +/**************************************************************************/ +/*! + @brief Sends a string to a pre-determined end point (UART, etc.). + + @param[in] str + Text to send + + @note This function is only called when using the GCC-compiler + in Codelite or running the Makefile manually. This function + will not be called when using the C library in Crossworks for + ARM. +*/ +/**************************************************************************/ +int puts(const char * str) +{ + // There must be at least 1ms between USB frames (of up to 64 bytes) + // This buffers all data and writes it out from the buffer one frame + // and one millisecond at a time + #ifdef CFG_PRINTF_USBCDC + if (USB_Configuration) + { + while(*str) + cdcBufferWrite(*str++); + // Check if we can flush the buffer now or if we need to wait + unsigned int currentTick = systickGetTicks(); + if (currentTick != lastTick) + { + uint8_t frame[64]; + uint32_t bytesRead = 0; + while (cdcBufferDataPending()) + { + // Read up to 64 bytes as long as possible + bytesRead = cdcBufferReadLen(frame, 64); + USB_WriteEP (CDC_DEP_IN, frame, bytesRead); + systickDelay(1); + } + lastTick = currentTick; + } + } + #else + // Handle output character by character in __putchar + while(*str) __putchar(*str++); + #endif + + return 0; +} +#endif diff --git a/core/sysinit.h b/core/sysinit.h new file mode 100644 index 0000000..5fce517 --- /dev/null +++ b/core/sysinit.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file sysinit.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __SYSINIT_H__ +#define __SYSINIT_H__ + +#include "projectconfig.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +// Function prototypes +void systemInit(); + +#endif \ No newline at end of file diff --git a/core/systick/systick.c b/core/systick/systick.c new file mode 100644 index 0000000..1edbf0c --- /dev/null +++ b/core/systick/systick.c @@ -0,0 +1,229 @@ +/**************************************************************************/ +/*! + @file systick.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the 24-bit 'system tick' clock, which can be used as a + generic timer or to control time sharing with an embedded real-time + operating system (such as FreeRTOS). + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/systick/systick.h" + + void main (void) + { + cpuInit(); + + // Start systick timer with one tick every 10ms + systickInit(10); + + while(1) + { + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "systick.h" + +#ifdef CFG_SDCARD +#include "drivers/fatfs/diskio.h" +volatile uint32_t fatTicks = 0; +#endif + +volatile uint32_t systickTicks = 0; // 1ms tick counter +volatile uint32_t systickRollovers = 0; + +/**************************************************************************/ +/*! + @brief Systick interrupt handler +*/ +/**************************************************************************/ +void SysTick_Handler (void) +{ + systickTicks++; + + // Increment rollover counter + if (systickTicks == 0xFFFFFFFF) systickRollovers++; + + #ifdef CFG_SDCARD + fatTicks++; + if (fatTicks == 10) + { + fatTicks = 0; + disk_timerproc(); + } + #endif +} + +/**************************************************************************/ +/*! + @brief Configures the systick timer + + @param[in] ticks + The number of clock cycles between each tick of the + systick timer. for example, 'CFG_CPU_CCLK / 1000' = + 1 millisecond. This value must not exceed 0x00FFFFFF. +*/ +/**************************************************************************/ +static uint32_t systickConfig(uint32_t ticks) +{ + // Check if 'ticks' is greater than maximum value + if (ticks > SYSTICK_STRELOAD_MASK) + { + return (1); + } + + // Reset counter + systickTicks = 0; + + // Set reload register + SYSTICK_STRELOAD = (ticks & SYSTICK_STRELOAD_MASK) - 1; + + // Load the systick counter value + SYSTICK_STCURR = 0; + + // Enable systick IRQ and timer + SYSTICK_STCTRL = SYSTICK_STCTRL_CLKSOURCE | + SYSTICK_STCTRL_TICKINT | + SYSTICK_STCTRL_ENABLE; + + return (0); +} + +/**************************************************************************/ +/*! + @brief Initialises the systick timer + + @param[in] delayMs + The number of milliseconds between each tick of the systick + timer. + + @note The shortest possible delay is 1 millisecond, which will + allow fine grained delays, but will cause more load on the + system than a 10mS delay. The resolution of the systick + timer needs to be balanced with the amount of processing + time you can spare. The delay should really only be set + to 1 mS if you genuinely have a need for 1mS delays, + otherwise a higher value like 5 or 10 mS is probably + more appropriate. +*/ +/**************************************************************************/ +void systickInit (uint32_t delayMs) +{ + systickConfig ((CFG_CPU_CCLK / 1000) * delayMs); +} + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for 'delayTicks' ticks on the + systick timer. For example: systickDelay(100) would cause + a blocking delay for 100 ticks of the systick timer. + + @param[in] delayTicks + The number of systick ticks to cause a blocking delay for + + @Note This function takes into account the fact that the tick + counter may eventually roll over to 0 once it reaches + 0xFFFFFFFF. +*/ +/**************************************************************************/ +void systickDelay (uint32_t delayTicks) +{ + uint32_t curTicks; + curTicks = systickTicks; + + // Make sure delay is at least 1 tick in case of division, etc. + if (delayTicks == 0) delayTicks = 1; + + if (curTicks > 0xFFFFFFFF - delayTicks) + { + // Rollover will occur during delay + while (systickTicks >= curTicks) + { + while (systickTicks < (delayTicks - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((systickTicks - curTicks) < delayTicks); + } +} + +/**************************************************************************/ +/*! + @brief Returns the current value of the systick timer counter. + This value is incremented by one every time an interrupt + fires for the systick timer. +*/ +/**************************************************************************/ +uint32_t systickGetTicks(void) +{ + return systickTicks; +} + +/**************************************************************************/ +/*! + @brief Returns the current value of the systick timer rollover + counter. This value is incremented by one every time the + tick counter rolls over from 0xFFFFFFFF to 0. +*/ +/**************************************************************************/ +uint32_t systickGetRollovers(void) +{ + return systickRollovers; +} + +/**************************************************************************/ +/*! + @brief Returns the approximate number of seconds that the + systick timer has been running. +*/ +/**************************************************************************/ +uint32_t systickGetSecondsActive(void) +{ + uint32_t currentTick = systickTicks; + uint32_t rollovers = systickRollovers; + uint32_t secsActive = currentTick / (1000 / CFG_SYSTICK_DELAY_IN_MS); + secsActive += rollovers * (0xFFFFFFFF / (1000 / CFG_SYSTICK_DELAY_IN_MS)); + + return secsActive; +} + diff --git a/core/systick/systick.h b/core/systick/systick.h new file mode 100644 index 0000000..fd27ffe --- /dev/null +++ b/core/systick/systick.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file systick.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SYSTICK_H_ +#define _SYSTICK_H_ + +#include "projectconfig.h" + +void systickInit (uint32_t delayMs); +void systickDelay (uint32_t delayTicks); +uint32_t systickGetTicks(void); +uint32_t systickGetRollovers(void); +uint32_t systickGetSecondsActive(void); + +#endif \ No newline at end of file diff --git a/core/timer16/timer16.c b/core/timer16/timer16.c new file mode 100644 index 0000000..dfc3a1e --- /dev/null +++ b/core/timer16/timer16.c @@ -0,0 +1,505 @@ +/**************************************************************************/ +/*! + @file timer16.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Generic code for both 16-bit timers. + + @warning 16-bit timers are limited to roughly ~0.91ms (or 910uS) on + a system running at 72MHz since: + @code + 1 mS = CFG_CPU_CCLK / 1000 + = 72000000 / 1000 + = 72000 'ticks' + @endcode + Meaning that 0xFFFF (65535) 'ticks' = 0.910208 milliseconds + or 910 microseconds. + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + // Instantiated in timer16.h + extern volatile uint32_t timer16_0_counter; + ... + cpuInit(); + + // Initialise timer0 with a delay of 0xFFFF, which will cause the + // timer interrupt to fire every 65535 ticks and increment + // timer16_0_counter by 1 + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + // At this point timer16_0_counter should start incrementing by 1 + // every 65535 ticks + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "timer16.h" + +volatile uint32_t timer16_0_counter = 0; +volatile uint32_t timer16_1_counter = 0; + +#ifdef CFG_PWM + volatile uint32_t pwmCounter = 0; + extern volatile uint32_t pwmMaxPulses; // See drivers/pwm/pwm.c +#endif + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + clock ticks. + + @note The exact duration of this delay depends on the speed of the + system clock, but it will invariably be short because of the + 16-bit limitation. For example, on a system with a 72MHz + clock, a 1mS delay would be equal to 72,000 ticks, which is + already above the maximum 16-bit value of 65,535. Thus, the + maximum delay measured in mS with a 72MHz clock is ~0.91mS. + + @param[in] timerNum + The 16-bit timer to user (0..1) + @param[in] delayInTicks + The number of clock ticks to delay (0..65534) + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + int main(void) + { + cpuInit(); + + // Initialise timer 0 ... delay is provided but not used here + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + while(1) + { + // Cause blocking delay for 36000 ticks (0.5mS @ 72MHz) + // Note: The delay must be 65534 or less (16-bit value) + timer16DelayTicks(0, 36000); + } + } + @endcode +*/ +/**************************************************************************/ +void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks) +{ + // ToDo: Verify incoming value + + if (timerNum == 0) + { + /* Reset the timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B0PR = 0x00; + + TMR_TMR16B0MR0 = delayInTicks; + + /* Reset all interrupts */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED); + } + + else if (timerNum == 1) + { + /* Reset the timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B1PR = 0x00; + + TMR_TMR16B1MR0 = delayInTicks; + + /* Reset all interrupts */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED); + } + + return; +} + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + microseconds + + @warning The maximum delay in uS will depend on the clock speed, + but running at 72MHz the maximum delay (MR = 0xFFFF) + would be 910uS (0xFFFF / 72 = 910), or 0.91 milliseconds. + + @param[in] timerNum + The 16-bit timer to user (0..1) + @param[in] delayInUs + The number of microseconds to wait + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + int main(void) + { + cpuInit(); + + // Initialise timer 0 ... delay is provided but not used here + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + while(1) + { + // Cause blocking delay for 500 microseconds (0.5mS) + timer16DelayUS(0, 500); + } + } + @endcode +*/ +/**************************************************************************/ +void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS) +{ + // ToDo: Check if the appropriate timer is enabled first? + + if (timerNum == 0) + { + /* Reset the timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B0PR = 0x00; + + TMR_TMR16B0MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000); + + /* Reset all interrupts */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED); + } + + else if (timerNum == 1) + { + /* Reset the timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B1PR = 0x00; + + TMR_TMR16B1MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000); + + /* Reset all interrupts */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED); + } + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 16-bit timer 0 +*/ +/**************************************************************************/ +void TIMER16_0_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MR0; + + /* Increment timer counter by 1 (it will automatically roll back to 0) */ + timer16_0_counter++; + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 16-bit timer 1 +*/ +/**************************************************************************/ +void TIMER16_1_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MR0; + + /* Increment timer counter by 1 (it will automatically roll back to 0) */ + timer16_1_counter++; + + #ifdef CFG_PWM + /* Check if the PWM output should be disabled after pwmMaxPulses pulses */ + /* See "drivers/pwm/pwm.c" */ + if (TMR_TMR16B1IR & TMR_TMR16B1IR_MR3) + { + /* Clear the interrupt flag */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MR3; + + if (pwmMaxPulses > 0) + { + pwmCounter++; + if (pwmCounter == pwmMaxPulses) + { + /* Disable interrupt on MR3 */ + TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK); + /* Disable Timer */ + TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK); + /* Reset the counter variables */ + pwmCounter = 0; + pwmMaxPulses = 0; + } + } + } + #endif + + return; +} + +/**************************************************************************/ +/*! + @brief Enables the specified timer + + @param[in] timerNum + The 16-bit timer to enable (0..1) +*/ +/**************************************************************************/ +void timer16Enable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + } + + else if (timerNum == 1) + { + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Disables the specified timer + + @param[in] timerNum + The 16-bit timer to disable (0..1) +*/ +/**************************************************************************/ +void timer16Disable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_DISABLED; + } + + else if (timerNum == 1) + { + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_DISABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Resets the specified timer + + @param[in] timerNum + The 16-bit timer to reset (0..1) +*/ +/**************************************************************************/ +void timer16Reset(uint8_t timerNum) +{ + uint32_t regVal; + + if ( timerNum == 0 ) + { + regVal = TMR_TMR16B0TCR; + regVal |= TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + TMR_TMR16B0TCR = regVal; + } + + else if (timerNum == 1) + { + regVal = TMR_TMR16B1TCR; + regVal |= TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + TMR_TMR16B1TCR = regVal; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the specified 16-bit timer, sets the timer + interval, resets the timer, and configures the interrupt + handler. + + Initialises a 16-bit timer with the supplied timer interval (the + amount of time that passes between each timer 'tick'). Every time that + this interval elapses, the timer's interrupt will be fired and the + appropriate counter variable will be incremented by one (For example, + with CT16B0, 'timer16_0_counter' would be incremented). + + @param[in] timerNum + The 16-bit timer to initiliase (0..1) + @param[in] timerInterval + The number of clock 'ticks' between resets (0..65534) + + @warning Care needs to be taken when configuring the timers since + the pins are all multiplexed with other peripherals. This + code is provided as a starting point, but it will need to + be adjusted according to your own situation and + pin/peripheral requirements +*/ +/**************************************************************************/ +void timer16Init(uint8_t timerNum, uint16_t timerInterval) +{ + // If timerInterval is invalid, use the default value + if (timerInterval < 1) + { + timerInterval = TIMER16_DEFAULTINTERVAL; + } + + if ( timerNum == 0 ) + { + /* Enable the clock for CT16B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B0); + + /* The physical pins associated with CT16B0 are not enabled by + default in order to avoid conflicts with other peripherals. + Pin 0.10 (CT16B0_MAT2), for example, can not be used while + debugging with a hardware debugger. If you require one or + more of these pins, simply uncomment the code below */ + + /* Configure PIO0.2 as Timer0_16 CAP0 */ + // IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK; + // IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_CT16B0_CAP0; + + /* Configure PIO0.8 as Timer0_16 MAT0 */ + // IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK; + // IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_CT16B0_MAT0; + + /* Configure PIO0.9 as Timer0_16 MAT1 */ + // IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK; + // IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_CT16B0_MAT1; + + /* Configure PIO0.10 as Timer0_16 MAT3 */ + // IOCON_JTAG_TCK_PIO0_10 &= ~IOCON_JTAG_TCK_PIO0_10_FUNC_MASK; + // IOCON_JTAG_TCK_PIO0_10 |= IOCON_JTAG_TCK_PIO0_10_FUNC_CT16B0_MAT2; + + timer16_0_counter = 0; + TMR_TMR16B0MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR16B0MCR = (TMR_TMR16B0MCR_MR0_INT_ENABLED | TMR_TMR16B0MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER0 interrupt */ + NVIC_EnableIRQ(TIMER_16_0_IRQn); + } + + else if ( timerNum == 1 ) + { + /* Enable the clock for CT16B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1); + + /* The physical pins associated with CT16B0 are not enabled by + default in order to avoid conflicts with other peripherals. + Pin 0.10 (CT16B0_MAT2), for example, can not be used while + debugging with a hardware debugger. If you require one or + more of these pins, simply uncomment the code below */ + + /* Configure PIO1.8 as Timer1_16 CAP0 */ + // IOCON_PIO1_8 &= ~IOCON_PIO1_8_FUNC_MASK; + // IOCON_PIO1_8 |= IOCON_PIO1_8_FUNC_CT16B1_CAP0; + + /* Configure PIO1.9 as Timer1_16 MAT0 */ + // IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK; + // IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0; + + /* Configure PIO1.10 as Timer1_16 MAT1 */ + // IOCON_PIO1_10 &= ~IOCON_PIO1_10_FUNC_MASK; + // IOCON_PIO1_10 |= IOCON_PIO1_10_FUNC_CT16B1_MAT1; + + timer16_1_counter = 0; + TMR_TMR16B1MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR0_INT_ENABLED | TMR_TMR16B1MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER1 Interrupt */ + NVIC_EnableIRQ(TIMER_16_1_IRQn); + } + return; +} diff --git a/core/timer16/timer16.h b/core/timer16/timer16.h new file mode 100644 index 0000000..dda4d9c --- /dev/null +++ b/core/timer16/timer16.h @@ -0,0 +1,59 @@ +/**************************************************************************/ +/*! + @file timer16.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __TIMER16_H__ +#define __TIMER16_H__ + +#include "projectconfig.h" + +#define TIMER16_DEFAULTINTERVAL (0xFFFF) // ~0.91mS @ 72MHz, ~1.37mS @ 48MHz + +#define TIMER16_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000) +#define TIMER16_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000) + +void TIMER16_0_IRQHandler(void); +void TIMER16_1_IRQHandler(void); + +void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks); +void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS); +void timer16Enable(uint8_t timerNum); +void timer16Disable(uint8_t timerNum); +void timer16Reset(uint8_t timerNum); +void timer16Init(uint8_t timerNum, uint16_t timerInterval); + +#endif diff --git a/core/timer32/timer32.c b/core/timer32/timer32.c new file mode 100644 index 0000000..cccd377 --- /dev/null +++ b/core/timer32/timer32.c @@ -0,0 +1,344 @@ +/**************************************************************************/ +/*! + @file timer32.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for 32-bit timers. By default, the timers are configured + to generate an interrupt once every 100 microseconds, incrementing a + global variable once per tick. + + @warning Please note that the ROM-based USB drivers on the LPC1343 + require the use of 32-bit Timer 1. If you plan on using the + ROM-based USB functionality, you should restrict your timer + usage to 32-bit timer 0. + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer32/timer32.h" + ... + cpuInit(); + + // Initialise 32-bit timer 0 with 100uS ticks + timer32Init(0, TIMER32_DEFAULTINTERVAL); + + // Enable timer 0 + timer32Enable(0); + + // Cause a blocking delay for 1 second (1000mS) + timer32Delay(0, TIMER32_DELAY_1MS * 1000); + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "timer32.h" + +volatile uint32_t timer32_0_counter = 0; +volatile uint32_t timer32_1_counter = 0; + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + timer ticks. The duration of each 'tick' is determined by + the 'timerInterval' property supplied to timer32Init. + + @param[in] timerNum + The 32-bit timer to user (0..1) + @param[in] delay + The number of counter increments to wait +*/ +/**************************************************************************/ +void timer32Delay(uint8_t timerNum, uint32_t delay) +{ + uint32_t curTicks; + + if (timerNum == 0) + { + curTicks = timer32_0_counter; + if (curTicks > 0xFFFFFFFF - delay) + { + // Rollover will occur during delay + while (timer32_0_counter >= curTicks) + { + while (timer32_0_counter < (delay - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((timer32_0_counter - curTicks) < delay); + } + } + + else if (timerNum == 1) + { + curTicks = timer32_1_counter; + if (curTicks > 0xFFFFFFFF - delay) + { + // Rollover will occur during delay + while (timer32_1_counter >= curTicks) + { + while (timer32_1_counter < (delay - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((timer32_1_counter - curTicks) < delay); + } + } + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 32-bit timer 0 +*/ +/**************************************************************************/ +void TIMER32_0_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR32B0IR = TMR_TMR32B0IR_MR0; + + /* If you wish to perform some action after each timer 'tick' (such as + incrementing a counter variable) you can do so here */ + timer32_0_counter++; + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 32-bit timer 1 +*/ +/**************************************************************************/ +void TIMER32_1_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR32B1IR = TMR_TMR32B1IR_MR0; + + /* If you wish to perform some action after each timer 'tick' (such as + incrementing a counter variable) you can do so here */ + timer32_1_counter++; + + return; +} + +/**************************************************************************/ +/*! + @brief Enables the specified timer + + @param[in] timerNum + The 32-bit timer to enable (0..1) +*/ +/**************************************************************************/ +void timer32Enable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED; + } + + else if (timerNum == 1) + { + TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_ENABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Disables the specified timer + + @param[in] timerNum + The 32-bit timer to disable (0..1) +*/ +/**************************************************************************/ +void timer32Disable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + } + + else if (timerNum == 1) + { + TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_DISABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Resets the specified timer + + @param[in] timerNum + The 32-bit timer to reset (0..1) +*/ +/**************************************************************************/ +void timer32Reset(uint8_t timerNum) +{ + uint32_t regVal; + + if ( timerNum == 0 ) + { + regVal = TMR_TMR32B0TCR; + regVal |= TMR_TMR32B0TCR_COUNTERRESET_ENABLED; + TMR_TMR32B0TCR = regVal; + } + + else if (timerNum == 1) + { + regVal = TMR_TMR32B1TCR; + regVal |= TMR_TMR32B1TCR_COUNTERRESET_ENABLED; + TMR_TMR32B1TCR = regVal; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the specified 32-bit timer, and configures the + timer to raise an interrupt and reset on match on MR0. + + @param[in] timerNum + The 32-bit timer to initiliase (0..1) + @param[in] timerInterval + The number of clock 'ticks' between resets (0..0xFFFFFFFF) + + @note Care needs to be taken when configuring the timers since the + pins are all multiplexed with other peripherals. This code is + provided as a starting point, but it will need to be adjusted + according to your own situation and pin/peripheral requirements +*/ +/**************************************************************************/ +void timer32Init(uint8_t timerNum, uint32_t timerInterval) +{ + // If timerInterval is invalid, use the default value + if (timerInterval < 1) + { + timerInterval = TIMER32_DEFAULTINTERVAL; + } + + if ( timerNum == 0 ) + { + /* Enable the clock for CT32B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); + + /* The physical pins associated with CT32B0 are not enabled by + default in order to avoid conflicts with other peripherals. If + you wish to use any of the pin-dependant functionality, simply + uncomment the appropriate lines below. */ + + /* Configure PIO1.5 as Timer0_32 CAP0 */ + // IOCON_PIO1_5 &= ~IOCON_PIO1_5_FUNC_MASK; + // IOCON_PIO1_5 |= IOCON_PIO1_5_FUNC_CT32B0_CAP0; + + /* Configure PIO1.6 as Timer0_32 MAT0 */ + // IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK; + // IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_CT32B0_MAT0; + + /* Configure PIO1.7 as Timer0_32 MAT1 */ + // IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK; + // IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_CT32B0_MAT1; + + /* Configure PIO0.1 as Timer0_32 MAT2 */ + // IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + // IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2; + + /* Configure PIO0.11 as Timer0_32 MAT3 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TDI_PIO0_11 &= ~IOCON_JTAG_TDI_PIO0_11_FUNC_MASK; + // IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_CT32B0_MAT3; + + timer32_0_counter = 0; + TMR_TMR32B0MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B0MCR = (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER0 interrupt */ + NVIC_EnableIRQ(TIMER_32_0_IRQn); + } + + else if ( timerNum == 1 ) + { + /* Enable the clock for CT32B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1); + + /* The physical pins associated with CT32B0 are not enabled by + default in order to avoid conflicts with other peripherals. */ + + /* Configure PIO1.0 as Timer1_32 CAP0 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TMS_PIO1_0 &= ~IOCON_JTAG_TMS_PIO1_0_FUNC_MASK; + // IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_CT32B1_CAP0; + + /* Configure PIO1.1 as Timer1_32 MAT0 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TDO_PIO1_1 &= ~IOCON_JTAG_TDO_PIO1_1_FUNC_MASK; + // IOCON_JTAG_TDO_PIO1_1 |= IOCON_JTAG_TDO_PIO1_1_FUNC_CT32B1_MAT0; + + /* Configure PIO1.2 as Timer1_32 MAT1 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_nTRST_PIO1_2 &= ~IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK; + // IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_CT32B1_MAT1; + + /* Configure PIO1.3 as Timer1_32 MAT2 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_SWDIO_PIO1_3 &= ~IOCON_SWDIO_PIO1_3_FUNC_MASK; + // IOCON_SWDIO_PIO1_3 |= IOCON_SWDIO_PIO1_3_FUNC_CT32B1_MAT2; + + /* Configure PIO1.4 as Timer1_32 MAT3 */ + // IOCON_PIO1_4 &= ~IOCON_PIO1_4_FUNC_MASK; + // IOCON_PIO1_4 |= IOCON_PIO1_4_FUNC_CT32B1_MAT3; + + timer32_1_counter = 0; + TMR_TMR32B1MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B1MCR = (TMR_TMR32B1MCR_MR0_INT_ENABLED | TMR_TMR32B1MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER1 Interrupt */ + NVIC_EnableIRQ(TIMER_32_1_IRQn); + } + return; +} + + diff --git a/core/timer32/timer32.h b/core/timer32/timer32.h new file mode 100644 index 0000000..ef2dc5e --- /dev/null +++ b/core/timer32/timer32.h @@ -0,0 +1,66 @@ +/**************************************************************************/ +/*! + @file timer32.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __TIMER32_H__ +#define __TIMER32_H__ + +#include "projectconfig.h" + +#define TIMER32_CCLK_1US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000) +#define TIMER32_CCLK_10US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100000) +#define TIMER32_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000) +#define TIMER32_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000) +#define TIMER32_CCLK_10MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100) +#define TIMER32_CCLK_100MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10) +#define TIMER32_CCLK_1S (CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) +#define TIMER32_DEFAULTINTERVAL (TIMER32_CCLK_100US) + +#define TIMER32_DELAY_100US (1) // 100uS delay = 1 tick +#define TIMER32_DELAY_1MS (10) // 1mS delay = 10 ticks +#define TIMER32_DELAY_1S (10000) // 1S delay = 10000 ticks + +void TIMER32_0_IRQHandler(void); +void TIMER32_1_IRQHandler(void); + +void timer32Delay(uint8_t timerNum, uint32_t delay); +void timer32Enable(uint8_t timerNum); +void timer32Disable(uint8_t timerNum); +void timer32Reset(uint8_t timerNum); +void timer32Init(uint8_t timerNum, uint32_t timerInterval); + +#endif diff --git a/core/uart/uart.c b/core/uart/uart.c new file mode 100644 index 0000000..83bf2e1 --- /dev/null +++ b/core/uart/uart.c @@ -0,0 +1,347 @@ +/**************************************************************************/ +/*! + @file uart.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for UART-based communication. Incoming text is stored + in a FIFO Queue for safer processing. + + @section Example: Sending text via UART + + @code + #include "core/cpu/cpu.h" + #include "core/uart/uart.h" + ... + #define UARTBUFFERSIZE 5 + ... + cpuInit(); + uartInit(57600); + ... + uint8_t uartBuffer[UARTBUFFERSIZE] = { 'T', 'e', 's', 't', '\n' }; + + // Send contents of uartBuffer + uartSend((uint8_t *)uartBuffer, UARTBUFFERSIZE); + @endcode + + @section Example: Reading from UART + + @code + + #include "core/cpu/cpu.h" + #include "core/uart/uart.h" + + cpuInit(); + uartInit(57600); + + // Get a reference to the UART control block + uart_pcb_t *pcb = uartGetPCB(); + + // Read any text available in the queue + while (uartRxBufferDataPending()) + { + // Read the first available character + uint8_t c = uartRxBufferRead(); + + // read out the data in the buffer and echo it back to the host. + switch (c) + { + case '\r': + printf("\n\r"); + break; + default: + printf("%c", c); + break; + } + } + + #endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include + +#include "uart.h" + +#ifdef CFG_INTERFACE_UART + #include "core/cmd/cmd.h" +#endif + +/**************************************************************************/ +/*! + UART protocol control block, which is used to safely access the + RX FIFO buffer from elsewhere in the code. This should be accessed + through 'uartGetPCB()'. +*/ +/**************************************************************************/ +static uart_pcb_t pcb; + +/**************************************************************************/ +/*! + IRQ to handle incoming data, etc. +*/ +/**************************************************************************/ +void UART_IRQHandler(void) +{ + uint8_t IIRValue, LSRValue; + uint8_t Dummy = Dummy; + + IIRValue = UART_U0IIR; + IIRValue &= ~(UART_U0IIR_IntStatus_MASK); /* skip pending bit in IIR */ + IIRValue &= UART_U0IIR_IntId_MASK; /* check bit 1~3, interrupt identification */ + + // 1.) Check receiver line status + if (IIRValue == UART_U0IIR_IntId_RLS) + { + LSRValue = UART_U0LSR; + // Check for errors + if (LSRValue & (UART_U0LSR_OE | UART_U0LSR_PE | UART_U0LSR_FE | UART_U0LSR_RXFE | UART_U0LSR_BI)) + { + /* There are errors or break interrupt */ + /* Read LSR will clear the interrupt */ + pcb.status = LSRValue; + Dummy = UART_U0RBR; /* Dummy read on RX to clear interrupt, then bail out */ + return; + } + // No error and receive data is ready + if (LSRValue & UART_U0LSR_RDR_DATA) + { + /* If no error on RLS, normal ready, save into the data buffer. */ + /* Note: read RBR will clear the interrupt */ + uartRxBufferWrite(UART_U0RBR); + } + } + + // 2.) Check receive data available + else if (IIRValue == UART_U0IIR_IntId_RDA) + { + // Add incoming text to UART buffer + uartRxBufferWrite(UART_U0RBR); + } + + // 3.) Check character timeout indicator + else if (IIRValue == UART_U0IIR_IntId_CTI) + { + /* Bit 9 as the CTI error */ + pcb.status |= 0x100; + } + + // 4.) Check THRE (transmit holding register empty) + else if (IIRValue == UART_U0IIR_IntId_THRE) + { + /* Check status in the LSR to see if valid data in U0THR or not */ + LSRValue = UART_U0LSR; + if (LSRValue & UART_U0LSR_THRE) + { + pcb.pending_tx_data = 0; + } + else + { + pcb.pending_tx_data= 1; + } + } + return; +} + +/**************************************************************************/ +/*! + @brief Get a pointer to the UART's protocol control block, which can + be used to control the RX FIFO buffer and check whether UART + has already been initialised or not. + + @section Example + + @code + // Make sure that UART is initialised + uart_pcb_t *pcb = uartGetPCB(); + if (!pcb->initialised) + { + uartInit(CFG_UART_BAUDRATE); + } + @endcode + +*/ +/**************************************************************************/ +uart_pcb_t *uartGetPCB() +{ + return &pcb; +} + +/**************************************************************************/ +/*! + @brief Initialises UART at the specified baud rate. + + @param[in] baudRate + The baud rate to use when configuring the UART. +*/ +/**************************************************************************/ +void uartInit(uint32_t baudrate) +{ + uint32_t fDiv; + uint32_t regVal; + + NVIC_DisableIRQ(UART_IRQn); + + // Clear protocol control blocks + memset(&pcb, 0, sizeof(uart_pcb_t)); + pcb.pending_tx_data = 0; + uartRxBufferInit(); + + /* Set 1.6 UART RXD */ + IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK; + IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_UART_RXD; + + /* Set 1.7 UART TXD */ + IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK; + IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_UART_TXD; + + /* Enable UART clock */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_UART); + SCB_UARTCLKDIV = SCB_UARTCLKDIV_DIV1; /* divided by 1 */ + + /* 8 bits, no Parity, 1 Stop bit */ + UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars | + UART_U0LCR_Stop_Bit_Select_1Bits | + UART_U0LCR_Parity_Disabled | + UART_U0LCR_Parity_Select_OddParity | + UART_U0LCR_Break_Control_Disabled | + UART_U0LCR_Divisor_Latch_Access_Enabled); + + /* Baud rate */ + regVal = SCB_UARTCLKDIV; + fDiv = (((CFG_CPU_CCLK * SCB_SYSAHBCLKDIV)/regVal)/16)/baudrate; + + UART_U0DLM = fDiv / 256; + UART_U0DLL = fDiv % 256; + + /* Set DLAB back to 0 */ + UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars | + UART_U0LCR_Stop_Bit_Select_1Bits | + UART_U0LCR_Parity_Disabled | + UART_U0LCR_Parity_Select_OddParity | + UART_U0LCR_Break_Control_Disabled | + UART_U0LCR_Divisor_Latch_Access_Disabled); + + /* Enable and reset TX and RX FIFO. */ + UART_U0FCR = (UART_U0FCR_FIFO_Enabled | + UART_U0FCR_Rx_FIFO_Reset | + UART_U0FCR_Tx_FIFO_Reset); + + /* Read to clear the line status. */ + regVal = UART_U0LSR; + + /* Ensure a clean start, no data in either TX or RX FIFO. */ + while (( UART_U0LSR & (UART_U0LSR_THRE|UART_U0LSR_TEMT)) != (UART_U0LSR_THRE|UART_U0LSR_TEMT) ); + while ( UART_U0LSR & UART_U0LSR_RDR_DATA ) + { + /* Dump data from RX FIFO */ + regVal = UART_U0RBR; + } + + /* Set the initialised flag in the protocol control block */ + pcb.initialised = 1; + pcb.baudrate = baudrate; + + /* Enable the UART Interrupt */ + NVIC_EnableIRQ(UART_IRQn); + UART_U0IER = UART_U0IER_RBR_Interrupt_Enabled | UART_U0IER_RLS_Interrupt_Enabled; + + return; +} + +/**************************************************************************/ +/*! + @brief Sends the contents of supplied text buffer over UART. + + @param[in] bufferPtr + Pointer to the text buffer + @param[in] bufferPtr + The size of the text buffer + + @section Example + + @code + // Set 5-character text buffer + uint8_t uartBuffer[5] = { 'T', 'e', 's', 't', '\n' }; + // Send contents of uartBuffer + uartSend((uint8_t *)uartBuffer, 5); + @endcode + +*/ +/**************************************************************************/ +void uartSend (uint8_t *bufferPtr, uint32_t length) +{ + while (length != 0) + { + /* THRE status, contain valid data */ + while ( !(UART_U0LSR & UART_U0LSR_THRE) ); + UART_U0THR = *bufferPtr; + + bufferPtr++; + length--; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Sends a single byte over UART. + + @param[in] byte + Byte value to send + + @section Example + + @code + // Send 0xFF over UART + uartSendByte(0xFF); + // Send 'B' over UART (note single quotes) + uartSendByte('B'); + @endcode + +*/ +/**************************************************************************/ +void uartSendByte (uint8_t byte) +{ + /* THRE status, contain valid data */ + while ( !(UART_U0LSR & UART_U0LSR_THRE) ); + UART_U0THR = byte; + + return; +} + + + diff --git a/core/uart/uart.h b/core/uart/uart.h new file mode 100644 index 0000000..84538de --- /dev/null +++ b/core/uart/uart.h @@ -0,0 +1,78 @@ +/**************************************************************************/ +/*! + @file uart.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __UART_H__ +#define __UART_H__ + +#include "projectconfig.h" + +// Buffer used for circular fifo +typedef struct _uart_buffer_t +{ + uint8_t ep_dir; + volatile uint8_t len; + volatile uint8_t wr_ptr; + volatile uint8_t rd_ptr; + uint8_t buf[CFG_UART_BUFSIZE]; +} uart_buffer_t; + +// UART Protocol control block +typedef struct _uart_pcb_t +{ + BOOL initialised; + uint32_t baudrate; + uint32_t status; + uint32_t pending_tx_data; + uart_buffer_t rxfifo; +} uart_pcb_t; + +void UART_IRQHandler(void); +uart_pcb_t *uartGetPCB(); +void uartInit(uint32_t Baudrate); +void uartSend(uint8_t *BufferPtr, uint32_t Length); +void uartSendByte (uint8_t byte); + +// Rx Buffer access control +void uartRxBufferInit(); +uint8_t uartRxBufferRead(); +void uartRxBufferWrite(uint8_t data); +void uartRxBufferClearFIFO(); +uint8_t uartRxBufferDataPending(); +bool uartRxBufferReadArray(byte_t* rx, size_t* len); + +#endif diff --git a/core/uart/uart_buf.c b/core/uart/uart_buf.c new file mode 100644 index 0000000..a5d2863 --- /dev/null +++ b/core/uart/uart_buf.c @@ -0,0 +1,149 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file uart_buf.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include "uart.h" + +/**************************************************************************/ +/*! + Initialises the RX FIFO buffer +*/ +/**************************************************************************/ +void uartRxBufferInit() +{ + uart_pcb_t *pcb = uartGetPCB(); + pcb->rxfifo.len = 0; +} + +/**************************************************************************/ +/*! + Read one byte out of the RX buffer. This function will return the byte + located at the array index of the read pointer, and then increment the + read pointer index. If the read pointer exceeds the maximum buffer + size, it will roll over to zero. +*/ +/**************************************************************************/ +uint8_t uartRxBufferRead() +{ + uart_pcb_t *pcb = uartGetPCB(); + uint8_t data; + + data = pcb->rxfifo.buf[pcb->rxfifo.rd_ptr]; + pcb->rxfifo.rd_ptr = (pcb->rxfifo.rd_ptr + 1) % CFG_UART_BUFSIZE; + pcb->rxfifo.len--; + return data; +} + +/**************************************************************************/ +/*! + Read byte array from uart + */ +/**************************************************************************/ +bool uartRxBufferReadArray(byte_t* rx, size_t* len) +{ + uart_pcb_t *pcb = uartGetPCB(); + *len = 0; + + while(pcb->rxfifo.len != 0) + { + (*rx) = uartRxBufferRead(); + (*len)++; + rx++; + } + + return (*len != 0); +} + +/**************************************************************************/ +/*! + Write one byte into the RX buffer. This function will write one + byte into the array index specified by the write pointer and increment + the write index. If the write index exceeds the max buffer size, then it + will roll over to zero. +*/ +/**************************************************************************/ +void uartRxBufferWrite(uint8_t data) +{ + uart_pcb_t *pcb = uartGetPCB(); + + pcb->rxfifo.buf[pcb->rxfifo.wr_ptr] = data; + pcb->rxfifo.wr_ptr = (pcb->rxfifo.wr_ptr + 1) % CFG_UART_BUFSIZE; + pcb->rxfifo.len++; +} + +/**************************************************************************/ +/*! + Clear the fifo read and write pointers and set the length to zero. +*/ +/**************************************************************************/ +void uartRxBufferClearFIFO() +{ + uart_pcb_t *pcb = uartGetPCB(); + + pcb->rxfifo.rd_ptr = 0; + pcb->rxfifo.wr_ptr = 0; + pcb->rxfifo.len = 0; +} + +/**************************************************************************/ +/*! + Check whether there is any data pending on the RX buffer. +*/ +/**************************************************************************/ +uint8_t uartRxBufferDataPending() +{ + uart_pcb_t *pcb = uartGetPCB(); + + if (pcb->rxfifo.len != 0) + { + return 1; + } + + return 0; +} diff --git a/core/usbcdc/cdc.h b/core/usbcdc/cdc.h new file mode 100644 index 0000000..358129c --- /dev/null +++ b/core/usbcdc/cdc.h @@ -0,0 +1,236 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: CDC.h + * Purpose: USB Communication Device Class Definitions + * Version: V1.00 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_H +#define __CDC_H + +/*---------------------------------------------------------------------------- + * Definitions based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ +// Communication device class specification version 1.10 +#define CDC_V1_10 0x0110 + +// Communication interface class code +// (usbcdc11.pdf, 4.2, Table 15) +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +// Communication interface class subclass codes +// (usbcdc11.pdf, 4.3, Table 16) +#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_TELEPHONE_CONTROL_MODEL 0x03 +#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04 +#define CDC_CAPI_CONTROL_MODEL 0x05 +#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06 +#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07 + +// Communication interface class control protocol codes +// (usbcdc11.pdf, 4.4, Table 17) +#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01 + +// Data interface class code +// (usbcdc11.pdf, 4.5, Table 18) +#define CDC_DATA_INTERFACE_CLASS 0x0A + +// Data interface class protocol codes +// (usbcdc11.pdf, 4.7, Table 19) +#define CDC_PROTOCOL_ISDN_BRI 0x30 +#define CDC_PROTOCOL_HDLC 0x31 +#define CDC_PROTOCOL_TRANSPARENT 0x32 +#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50 +#define CDC_PROTOCOL_Q921_DATA_LINK 0x51 +#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52 +#define CDC_PROTOCOL_V42 0x90 +#define CDC_PROTOCOL_EURO_ISDN 0x91 +#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92 +#define CDC_PROTOCOL_CAPI 0x93 +#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD +#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE + +// Type values for bDescriptorType field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 24) +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 + +// Type values for bDescriptorSubtype field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 25) +#define CDC_HEADER 0x00 +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_DIRECT_LINE_MANAGEMENT 0x03 +#define CDC_TELEPHONE_RINGER 0x04 +#define CDC_REPORTING_CAPABILITIES 0x05 +#define CDC_UNION 0x06 +#define CDC_COUNTRY_SELECTION 0x07 +#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08 +#define CDC_USB_TERMINAL 0x09 +#define CDC_NETWORK_CHANNEL 0x0A +#define CDC_PROTOCOL_UNIT 0x0B +#define CDC_EXTENSION_UNIT 0x0C +#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D +#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E +#define CDC_ETHERNET_NETWORKING 0x0F +#define CDC_ATM_NETWORKING 0x10 + +// CDC class-specific request codes +// (usbcdc11.pdf, 6.2, Table 46) +// see Table 45 for info about the specific requests. +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A +#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETHERNET_PMP_FILTER 0x41 +#define CDC_GET_ETHERNET_PMP_FILTER 0x42 +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define CDC_GET_ETHERNET_STATISTIC 0x44 +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + +// Communication feature selector codes +// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) +#define CDC_ABSTRACT_STATE 0x01 +#define CDC_COUNTRY_SETTING 0x02 + +// Feature Status returned for ABSTRACT_STATE Selector +// (usbcdc11.pdf, 6.2.3, Table 48) +#define CDC_IDLE_SETTING (1 << 0) +#define CDC_DATA_MULTPLEXED_STATE (1 << 1) + + +// Control signal bitmap values for the SetControlLineState request +// (usbcdc11.pdf, 6.2.14, Table 51) +#define CDC_DTE_PRESENT (1 << 0) +#define CDC_ACTIVATE_CARRIER (1 << 1) + +// CDC class-specific notification codes +// (usbcdc11.pdf, 6.3, Table 68) +// see Table 67 for Info about class-specific notifications +#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00 +#define CDC_RESPONSE_AVAILABLE 0x01 +#define CDC_AUX_JACK_HOOK_STATE 0x08 +#define CDC_RING_DETECT 0x09 +#define CDC_NOTIFICATION_SERIAL_STATE 0x20 +#define CDC_CALL_STATE_CHANGE 0x28 +#define CDC_LINE_STATE_CHANGE 0x29 +#define CDC_CONNECTION_SPEED_CHANGE 0x2A + +// UART state bitmap values (Serial state notification). +// (usbcdc11.pdf, 6.3.5, Table 69) +#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred +#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred +#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred +#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection +#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection +#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier +#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier + + +/*---------------------------------------------------------------------------- + * Structures based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ + +// Header functional descriptor +// (usbcdc11.pdf, 5.2.3.1) +// This header must precede any list of class-specific descriptors. +typedef struct _CDC_HEADER_DESCRIPTOR{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // Header functional descriptor subtype + uint16_t bcdCDC; // USB CDC specification release version +} __attribute__((packed)) CDC_HEADER_DESCRIPTOR; + +//Call management functional descriptor +// (usbcdc11.pdf, 5.2.3.2) +// Describes the processing of calls for the communication class interface. +typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // call management functional descriptor subtype + uint8_t bmCapabilities; // capabilities that this configuration supports + uint8_t bDataInterface; // interface number of the data class interface used for call management (optional) +} __attribute__((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR; + +// Abstract control management functional descriptor +// (usbcdc11.pdf, 5.2.3.3) +// Describes the command supported by the communication interface class with the Abstract Control Model subclass code. +typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype + uint8_t bmCapabilities; // capabilities supported by this configuration +} __attribute__((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR; + +// Union functional descriptors +// (usbcdc11.pdf, 5.2.3.8) +// Describes the relationship between a group of interfaces that can be considered to form a functional unit. +typedef struct _CDC_UNION_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // union functional descriptor subtype + uint8_t bMasterInterface; // interface number designated as master +} __attribute__((packed)) CDC_UNION_DESCRIPTOR; + +// Union functional descriptors with one slave interface +// (usbcdc11.pdf, 5.2.3.8) +typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR { + CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor + uint8_t bSlaveInterfaces[1]; // Slave interface 0 +} __attribute__((packed)) CDC_UNION_1SLAVE_DESCRIPTOR; + +// Line coding structure +// Format of the data returned when a GetLineCoding request is received +// (usbcdc11.pdf, 6.2.13) +typedef struct _CDC_LINE_CODING { + uint32_t dwDTERate; // Data terminal rate in bits per second + uint8_t bCharFormat; // Number of stop bits + uint8_t bParityType; // Parity bit type + uint8_t bDataBits; // Number of data bits +} __attribute__((packed)) CDC_LINE_CODING; + +// Notification header +// Data sent on the notification endpoint must follow this header. +// see USB_SETUP_PACKET in file usb.h +typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER; + +#endif /* __CDC_H */ + diff --git a/core/usbcdc/cdc_buf.c b/core/usbcdc/cdc_buf.c new file mode 100644 index 0000000..8ffe6be --- /dev/null +++ b/core/usbcdc/cdc_buf.c @@ -0,0 +1,161 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file cdc_buf.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include "cdc_buf.h" + +static cdc_buffer_t cdcfifo; + +/**************************************************************************/ +/*! + Gets a pointer to the fifo buffer +*/ +/**************************************************************************/ +cdc_buffer_t *cdcGetBuffer() +{ + return &cdcfifo; +} + +/**************************************************************************/ +/*! + Initialises the RX FIFO buffer +*/ +/**************************************************************************/ +void cdcBufferInit() +{ + cdcfifo.len = 0; +} + +/**************************************************************************/ +/*! + Read one byte out of the RX buffer. This function will return the byte + located at the array index of the read pointer, and then increment the + read pointer index. If the read pointer exceeds the maximum buffer + size, it will roll over to zero. +*/ +/**************************************************************************/ +uint8_t cdcBufferRead() +{ + uint8_t data; + + data = cdcfifo.buf[cdcfifo.rd_ptr]; + cdcfifo.rd_ptr = (cdcfifo.rd_ptr + 1) % CFG_USBCDC_BUFFERSIZE; + cdcfifo.len--; + return data; +} + +/**************************************************************************/ +/*! + Reads x bytes from cdc buffer + */ +/**************************************************************************/ +uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len) +{ + uint32_t counter, actual; + counter = actual = 0; + + while(counter != len) + { + // Make sure we don't exceed buffer limits + if (cdcfifo.len > 0) + { + buf[counter] = cdcBufferRead(); + actual++; + counter++; + } + else + { + return actual; + } + } + + return actual; +} + +/**************************************************************************/ +/*! + Write one byte into the RX buffer. This function will write one + byte into the array index specified by the write pointer and increment + the write index. If the write index exceeds the max buffer size, then it + will roll over to zero. +*/ +/**************************************************************************/ +void cdcBufferWrite(uint8_t data) +{ + cdcfifo.buf[cdcfifo.wr_ptr] = data; + cdcfifo.wr_ptr = (cdcfifo.wr_ptr + 1) % CFG_USBCDC_BUFFERSIZE; + cdcfifo.len++; +} + +/**************************************************************************/ +/*! + Clear the fifo read and write pointers and set the length to zero. +*/ +/**************************************************************************/ +void cdcBufferClearFIFO() +{ + cdcfifo.rd_ptr = 0; + cdcfifo.wr_ptr = 0; + cdcfifo.len = 0; +} + +/**************************************************************************/ +/*! + Check whether there is any data pending on the RX buffer. +*/ +/**************************************************************************/ +uint8_t cdcBufferDataPending() +{ + if (cdcfifo.len != 0) + { + return 1; + } + + return 0; +} diff --git a/core/usbcdc/cdc_buf.h b/core/usbcdc/cdc_buf.h new file mode 100644 index 0000000..621e020 --- /dev/null +++ b/core/usbcdc/cdc_buf.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------- + * Name: cdc_buf.h + * Purpose: usb cdc buffer handling + * Version: V1.00 + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_BUF_H__ +#define __CDC_BUF_H__ + +#include "projectconfig.h" + +// Buffer used for circular fifo +typedef struct _cdc_buffer_t +{ + volatile uint8_t len; + volatile uint8_t wr_ptr; + volatile uint8_t rd_ptr; + uint8_t buf[CFG_USBCDC_BUFFERSIZE]; +} cdc_buffer_t; + +cdc_buffer_t * cdcGetBuffer(); +void cdcBufferInit(); +uint8_t cdcBufferRead(); +uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len); +void cdcBufferWrite(uint8_t data); +void cdcBufferClearFIFO(); +uint8_t cdcBufferDataPending(); + +#endif diff --git a/core/usbcdc/cdcuser.c b/core/usbcdc/cdcuser.c new file mode 100644 index 0000000..fc35bf9 --- /dev/null +++ b/core/usbcdc/cdcuser.c @@ -0,0 +1,351 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.c + * Purpose: USB Communication Device Class User module + * Version: V1.10 + *---------------------------------------------------------------------------- +* This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#include "projectconfig.h" + +#include "usb.h" +#include "usbhw.h" +#include "usbcfg.h" +#include "usbcore.h" +#include "cdc.h" +#include "cdcuser.h" +#include "cdc_buf.h" + +// unsigned char BulkBufIn [64]; // Buffer to store USB IN packet +unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet +unsigned char NotificationBuf [10]; + +CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8}; +unsigned short CDC_SerialState = 0x0000; +unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty + +/*---------------------------------------------------------------------------- + We need a buffer for incoming data on USB port because USB receives + much faster than UART transmits + *---------------------------------------------------------------------------*/ +/* Buffer masks */ +#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2) + // large enough for file transfer +#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul) + +/* Buffer read / write macros */ +#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0) +#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn)) +#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++]) +#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx) +#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1) +#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx)) + + +// CDC output buffer +typedef struct __CDC_BUF_T +{ + unsigned char data[CDC_BUF_SIZE]; + volatile unsigned int wrIdx; + volatile unsigned int rdIdx; +} CDC_BUF_T; + +CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data + +/*---------------------------------------------------------------------------- + read data from CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_RdOutBuf (char *buffer, const int *length) +{ + int bytesToRead, bytesRead; + + /* Read *length bytes, block if *bytes are not avaialable */ + bytesToRead = *length; + bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length); + bytesRead = bytesToRead; + + + // ... add code to check for underrun + + while (bytesToRead--) { + *buffer++ = CDC_BUF_RD(CDC_OutBuf); + } + return (bytesRead); +} + +/*---------------------------------------------------------------------------- + write data to CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_WrOutBuf (const char *buffer, int *length) +{ + int bytesToWrite, bytesWritten; + + // Write *length bytes + bytesToWrite = *length; + bytesWritten = bytesToWrite; + + + // ... add code to check for overwrite + + while (bytesToWrite) { + CDC_BUF_WR(CDC_OutBuf, *buffer++); // Copy Data to buffer + bytesToWrite--; + } + + return (bytesWritten); +} + +/*---------------------------------------------------------------------------- + check if character(s) are available at CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_OutBufAvailChar (int *availChar) +{ + *availChar = CDC_BUF_COUNT(CDC_OutBuf); + + return (0); +} +/* end Buffer handling */ + + +/*---------------------------------------------------------------------------- + CDC Initialisation + Initializes the data structures and serial port + Parameters: None + Return Value: None + *---------------------------------------------------------------------------*/ +void CDC_Init (void) +{ + CDC_DepInEmpty = 1; + CDC_SerialState = CDC_GetSerialState(); + + CDC_BUF_RESET(CDC_OutBuf); + + // Initialise the CDC buffer. This is required to buffer outgoing + // data (MCU to PC) since data can only be sent 64 bytes per frame + // with at least 1ms between frames. To see how the buffer is used, + // see 'puts' in systeminit.c + cdcBufferInit(); +} + + +/*---------------------------------------------------------------------------- + CDC SendEncapsulatedCommand Request Callback + Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SendEncapsulatedCommand (void) +{ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetEncapsulatedResponse Request Callback + Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetEncapsulatedResponse (void) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetCommFeature Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetCommFeature Request Callback + Called automatically on CDC Get_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC ClearCommFeature Request Callback + Called automatically on CDC CLEAR_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetLineCoding Request Callback + Called automatically on CDC SET_LINE_CODING Request + Parameters: none (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetLineCoding (void) +{ + CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0) + | (EP0Buf[1] << 8) + | (EP0Buf[2] << 16) + | (EP0Buf[3] << 24); + CDC_LineCoding.bCharFormat = EP0Buf[4]; + CDC_LineCoding.bParityType = EP0Buf[5]; + CDC_LineCoding.bDataBits = EP0Buf[6]; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetLineCoding Request Callback + Called automatically on CDC GET_LINE_CODING Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetLineCoding (void) +{ + EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF; + EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF; + EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF; + EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF; + EP0Buf[4] = CDC_LineCoding.bCharFormat; + EP0Buf[5] = CDC_LineCoding.bParityType; + EP0Buf[6] = CDC_LineCoding.bDataBits; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetControlLineState Request Callback + Called automatically on CDC SET_CONTROL_LINE_STATE Request + Parameters: ControlSignalBitmap + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) { + + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SendBreak Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: 0xFFFF start of Break + 0x0000 stop of Break + 0x#### Duration of Break + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) { + + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC_BulkIn call on DataIn Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void CDC_BulkIn(void) +{ +// int numBytesRead, numBytesAvail; +// +// // ToDo: Modify BulkIn to send incoming data to USB +// +// ser_AvailChar (&numBytesAvail); +// +// // ... add code to check for overwrite +// +// numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail); +// +// // send over USB +// if (numBytesRead > 0) { +// USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead); +// } +// else { +// CDC_DepInEmpty = 1; +// } +// +// +} + + +/*---------------------------------------------------------------------------- + CDC_BulkOut call on DataOut Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void CDC_BulkOut(void) +{ + int numBytesRead; + + // get data from USB into intermediate buffer + numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]); + + // ... add code to check for overwrite + + // store data in a buffer to transmit it over serial interface + CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead); +} + + +/*---------------------------------------------------------------------------- + Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69. + Parameters: none + Return Value: SerialState as defined in usbcdc11.pdf + *---------------------------------------------------------------------------*/ +unsigned short CDC_GetSerialState (void) +{ + CDC_SerialState = 0; + + return (CDC_SerialState); +} + + +/*---------------------------------------------------------------------------- + Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5. + *---------------------------------------------------------------------------*/ +void CDC_NotificationIn (void) +{ + NotificationBuf[0] = 0xA1; // bmRequestType + NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE) + NotificationBuf[2] = 0x00; // wValue + NotificationBuf[3] = 0x00; + NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first) + NotificationBuf[5] = 0x00; + NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first) + NotificationBuf[7] = 0x00; + NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first) + NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF; + + USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification +} diff --git a/core/usbcdc/cdcuser.h b/core/usbcdc/cdcuser.h new file mode 100644 index 0000000..25b63e3 --- /dev/null +++ b/core/usbcdc/cdcuser.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.h + * Purpose: USB Communication Device Class User module Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSER_H__ +#define __CDCUSER_H__ + +/* CDC buffer handling */ +extern int CDC_RdOutBuf (char *buffer, const int *length); +extern int CDC_WrOutBuf (const char *buffer, int *length); +extern int CDC_OutBufAvailChar (int *availChar); + + +/* CDC Data In/Out Endpoint Address */ +#define CDC_DEP_IN 0x83 +#define CDC_DEP_OUT 0x03 + +/* CDC Communication In Endpoint Address */ +#define CDC_CEP_IN 0x81 + +/* CDC Requests Callback Functions */ +extern uint32_t CDC_SendEncapsulatedCommand (void); +extern uint32_t CDC_GetEncapsulatedResponse (void); +extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetLineCoding (void); +extern uint32_t CDC_SetLineCoding (void); +extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap); +extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak); + +/* CDC Bulk Callback Functions */ +extern void CDC_BulkIn (void); +extern void CDC_BulkOut (void); + +/* CDC Notification Callback Function */ +extern void CDC_NotificationIn (void); + +/* CDC Initialization Function */ +extern void CDC_Init (void); + +/* CDC prepare the SERAIAL_STATE */ +extern unsigned short CDC_GetSerialState (void); + +/* flow control */ +extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty + +#endif /* __CDCUSER_H__ */ + diff --git a/core/usbcdc/config.h b/core/usbcdc/config.h new file mode 100644 index 0000000..ca265a0 --- /dev/null +++ b/core/usbcdc/config.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * config.h: config file for usbcdc example for NXP LPC13xx Family + * Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.07.19 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ + +/* +Overview: + This example shows how to use the USB driver to implement a CDC class USB peripheral. + To run this example, you must attach a USB cable to the board. See + the "Getting Started Guide" appendix for details. + +How to use: + Click the debug toolbar button. + Click the go button. + Plug the LPCXpresso's target side into a PC using a USB cable retrofit + or a 3rd party base board. + + * You should be able to see a new COM port on your PC. +*/ + +#include "projectconfig.h" + +#define USB_VENDOR_ID CFG_USB_VID // Vendor ID +#define USB_PROD_ID CFG_USB_PID // Product ID +#define USB_DEVICE 0x0100 // Device ID + +#define LED_PORT 0 // Port for led +#define LED_BIT 7 // Bit on port for led + + +/********************************************************************************* +** End Of File +*********************************************************************************/ diff --git a/core/usbcdc/usb.h b/core/usbcdc/usb.h new file mode 100644 index 0000000..b0cdb11 --- /dev/null +++ b/core/usbcdc/usb.h @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USB_H__ +#define __USB_H__ + + +typedef union { + uint16_t W; + struct { + uint8_t L; + uint8_t H; + } __attribute__((packed)) WB; +} __attribute__((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE { + struct _BM { + uint8_t Recipient : 5; + uint8_t Type : 2; + uint8_t Dir : 1; + } __attribute__((packed)) BM; + uint8_t B; +} __attribute__((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET { + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString/*[]*/; +} __attribute__((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__((packed)) USB_COMMON_DESCRIPTOR; + + +#endif /* __USB_H__ */ diff --git a/core/usbcdc/usbcfg.h b/core/usbcdc/usbcfg.h new file mode 100644 index 0000000..3b9481b --- /dev/null +++ b/core/usbcdc/usbcfg.h @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcfg.h + * Purpose: USB Custom Configuration + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific support + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ + +#ifndef __USBCFG_H__ +#define __USBCFG_H__ + + +//*** <<< Use Configuration Wizard in Context Menu >>> *** + + +/* +// USB Configuration +// USB Power +// Default Power Setting +// <0=> Bus-powered +// <1=> Self-powered +// Max Number of Interfaces <1-256> +// Max Number of Endpoints <1-32> +// Max Endpoint 0 Packet Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// DMA Transfer +// Use DMA for selected Endpoints +// Endpoint 0 Out +// Endpoint 0 In +// Endpoint 1 Out +// Endpoint 1 In +// Endpoint 2 Out +// Endpoint 2 In +// Endpoint 3 Out +// Endpoint 3 In +// Endpoint 4 Out +// Endpoint 4 In +// +// +*/ + +#define USB_POWER 0 +#define USB_IF_NUM 1 +#define USB_LOGIC_EP_NUM 5 +#define USB_EP_NUM 10 +#define USB_MAX_PACKET0 64 + +/* +// USB Event Handlers +// Device Events +// Power Event +// Reset Event +// Suspend Event +// Resume Event +// Remote Wakeup Event +// Start of Frame Event +// Error Event +// +// Endpoint Events +// Endpoint 0 Event +// Endpoint 1 Event +// Endpoint 2 Event +// Endpoint 3 Event +// Endpoint 4 Event +// Endpoint 5 Event +// Endpoint 6 Event +// Endpoint 7 Event +// Endpoint 8 Event +// Endpoint 9 Event +// Endpoint 10 Event +// Endpoint 11 Event +// Endpoint 12 Event +// Endpoint 13 Event +// Endpoint 14 Event +// Endpoint 15 Event +// +// USB Core Events +// Set Configuration Event +// Set Interface Event +// Set/Clear Feature Event +// +// +*/ + +#define USB_POWER_EVENT 0 +#define USB_RESET_EVENT 1 +#define USB_SUSPEND_EVENT 1 +#define USB_RESUME_EVENT 1 +#define USB_WAKEUP_EVENT 0 +#define USB_SOF_EVENT 1 +#define USB_ERROR_EVENT 0 +#define USB_EP_EVENT 0x000B +#define USB_CONFIGURE_EVENT 1 +#define USB_INTERFACE_EVENT 0 +#define USB_FEATURE_EVENT 0 + + +/* +// USB Class Support +// enables USB Class specific Requests +// Human Interface Device (HID) +// Interface Number <0-255> +// +// Mass Storage +// Interface Number <0-255> +// +// Audio Device +// Control Interface Number <0-255> +// Streaming Interface 1 Number <0-255> +// Streaming Interface 2 Number <0-255> +// +// Communication Device +// Control Interface Number <0-255> +// Bulk Interface Number <0-255> +// Max Communication Device Buffer Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// +// +*/ + +#define USB_CLASS 1 +#define USB_HID 0 +#define USB_HID_IF_NUM 0 +#define USB_MSC 0 +#define USB_MSC_IF_NUM 0 +#define USB_AUDIO 0 +#define USB_ADC_CIF_NUM 0 +#define USB_ADC_SIF1_NUM 1 +#define USB_ADC_SIF2_NUM 2 +#define USB_CDC 1 +#define USB_CDC_CIF_NUM 0 +#define USB_CDC_DIF_NUM 1 +#define USB_CDC_BUFSIZE CFG_USBCDC_BUFSIZE + +/* +// USB Vendor Support +// enables USB Vendor specific Requests +// +*/ +#define USB_VENDOR 0 + + +#endif /* __USBCFG_H__ */ diff --git a/core/usbcdc/usbcore.c b/core/usbcdc/usbcore.c new file mode 100644 index 0000000..2506dbb --- /dev/null +++ b/core/usbcdc/usbcore.c @@ -0,0 +1,1058 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.c + * Purpose: USB Core Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific requests + * Changed string descriptor handling + * Reworked Endpoint0 + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "projectconfig.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbdesc.h" +#include "usbuser.h" + +#if (USB_CLASS) + +#if (USB_AUDIO) +#include "audio.h" +#include "adcuser.h" +#endif + +#if (USB_HID) +#include "hid.h" +#include "hiduser.h" +#endif + +#if (USB_MSC) +#include "msc.h" +#include "mscuser.h" +extern MSC_CSW CSW; +#endif + +#if (USB_CDC) +#include "cdc.h" +#include "cdcuser.h" +#endif + +#endif + +#if (USB_VENDOR) +#include "vendor.h" +#endif + +uint16_t USB_DeviceStatus; +uint8_t USB_DeviceAddress; +volatile uint8_t USB_Configuration; +uint32_t USB_EndPointMask; +uint32_t USB_EndPointHalt; +uint32_t USB_EndPointStall; /* EP must stay stalled */ +uint8_t USB_NumInterfaces; +uint8_t USB_AltSetting[USB_IF_NUM]; + +uint8_t EP0Buf[USB_MAX_PACKET0]; + + +USB_EP_DATA EP0Data; + +USB_SETUP_PACKET SetupPacket; + + +/* + * Reset USB Core + * Parameters: None + * Return Value: None + */ + +void USB_ResetCore (void) { + + USB_DeviceStatus = USB_POWER; + USB_DeviceAddress = 0; + USB_Configuration = 0; + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; +} + + +/* + * USB Request - Setup Stage + * Parameters: None (global SetupPacket) + * Return Value: None + */ + +void USB_SetupStage (void) { + USB_ReadEP(0x00, (uint8_t *)&SetupPacket); +} + + +/* + * USB Request - Data In Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataInStage (void) { + uint32_t cnt; + + if (EP0Data.Count > USB_MAX_PACKET0) { + cnt = USB_MAX_PACKET0; + } else { + cnt = EP0Data.Count; + } + cnt = USB_WriteEP(0x80, EP0Data.pData, cnt); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Data Out Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataOutStage (void) { + uint32_t cnt; + + cnt = USB_ReadEP(0x00, EP0Data.pData); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Status In Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusInStage (void) { + USB_WriteEP(0x80, NULL, 0); +} + + +/* + * USB Request - Status Out Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusOutStage (void) { + USB_ReadEP(0x00, EP0Buf); +} + + +/* + * Get Status USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetStatus (void) { + uint32_t n, m; + uint16_t* ep0 = (uint16_t __attribute__((packed)) *)EP0Buf; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + EP0Data.pData = (uint8_t *)&USB_DeviceStatus; + break; + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + *ep0 = 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) { + *ep0 = (USB_EndPointHalt & m) ? 1 : 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set/Clear Feature USB Request + * Parameters: sc: 0 - Clear, 1 - Set + * (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetClrFeature (uint32_t sc) { + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) { + if (sc) { + USB_WakeUpCfg(TRUE); + USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; + } else { + USB_WakeUpCfg(FALSE); + USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; + } + } else { + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + return (FALSE); + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) { + if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) { + if (sc) { + USB_SetStallEP(n); + USB_EndPointHalt |= m; + } else { + if ((USB_EndPointStall & m) != 0) { + return (TRUE); + } + USB_ClrStallEP(n); +#if (USB_MSC) + if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0)) { + /* Compliance Test: rewrite CSW after unstall */ + if (CSW.dSignature == MSC_CSW_Signature) { + USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW)); + } + } +#endif + USB_EndPointHalt &= ~m; + } + } else { + return (FALSE); + } + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Address USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetAddress (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Descriptor USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetDescriptor (void) { + uint8_t *pD; + uint32_t len, n; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + switch (SetupPacket.wValue.WB.H) { + case USB_DEVICE_DESCRIPTOR_TYPE: + EP0Data.pData = (uint8_t *)USB_DeviceDescriptor; + len = USB_DEVICE_DESC_SIZE; + break; + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_ConfigDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + } + } + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + break; + case USB_STRING_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_StringDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_STRING_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_STRING_DESCRIPTOR *)pD)->bLength; + } + } + if (((USB_STRING_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; + break; + default: + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + switch (SetupPacket.wValue.WB.H) { +#if USB_HID + case HID_HID_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)USB_ConfigDescriptor + HID_DESC_OFFSET; + len = HID_DESC_SIZE; + break; + case HID_REPORT_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)HID_ReportDescriptor; + len = HID_ReportDescSize; + break; + case HID_PHYSICAL_DESCRIPTOR_TYPE: + return (FALSE); /* HID Physical Descriptor is not supported */ +#endif + default: + return (FALSE); + } + break; + default: + return (FALSE); + } + + if (EP0Data.Count > len) { + EP0Data.Count = len; + } + + return (TRUE); +} + +/* + * Get Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetConfiguration (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + // Added cast to avoid warnings due to USB_Configuration being volatile (KTownsend) + EP0Data.pData = (uint8_t *)&USB_Configuration; + break; + default: + return (FALSE); + } + return (TRUE); +} + +/* + * Set Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetConfiguration (void) { + USB_COMMON_DESCRIPTOR *pD; + uint32_t alt = 0; + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + + if (SetupPacket.wValue.WB.L) { + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == SetupPacket.wValue.WB.L) { + USB_Configuration = SetupPacket.wValue.WB.L; + USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces; + for (n = 0; n < USB_IF_NUM; n++) { + USB_AltSetting[n] = 0; + } + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall= 0x00000000; + USB_Configure(TRUE); + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_POWERED_MASK) { + USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; + } else { + USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; + } + } else { + UsbAddPtr((void **)&pD, ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (alt == 0) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + USB_EndPointMask |= m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + } + break; + } + UsbAddPtr((void **)&pD, pD->bLength); + } + } + else { + USB_Configuration = 0; + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure(FALSE); + } + + if (USB_Configuration != SetupPacket.wValue.WB.L) { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetInterface (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetInterface (void) { + USB_COMMON_DESCRIPTOR *pD; + uint32_t ifn = 0, alt = 0, old = 0, msk = 0; + uint32_t n, m; + uint32_t set; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if (USB_Configuration == 0) return (FALSE); + set = FALSE; + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue != USB_Configuration) { + UsbAddPtr((void **)&pD, ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + ifn = ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber; + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + msk = 0; + if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L)) { + set = TRUE; + old = USB_AltSetting[ifn]; + USB_AltSetting[ifn] = (uint8_t)alt; + } + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (ifn == SetupPacket.wIndex.WB.L) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (alt == SetupPacket.wValue.WB.L) { + USB_EndPointMask |= m; + USB_EndPointHalt &= ~m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + msk |= m; + } + else if ((alt == old) && ((msk & m) == 0)) { + USB_EndPointMask &= ~m; + USB_EndPointHalt &= ~m; + USB_DisableEP(n); + } + } + break; + } + UsbAddPtr((void **)&pD, pD->bLength); + } + break; + default: + return (FALSE); + } + + return (set); +} + +/* + * USB Endpoint 0 Event Callback + * Parameters: event + * Return Value: none + */ + +void USB_EndPoint0 (uint32_t event) { + + switch (event) { + case USB_EVT_SETUP: + USB_SetupStage(); + USB_DirCtrlEP(SetupPacket.bmRequestType.BM.Dir); + EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + switch (SetupPacket.bRequest) { + case USB_REQUEST_GET_STATUS: + if (!USB_ReqGetStatus()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_CLEAR_FEATURE: + if (!USB_ReqSetClrFeature(0)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_FEATURE: + if (!USB_ReqSetClrFeature(1)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_ADDRESS: + if (!USB_ReqSetAddress()) { + goto stall_i; + } + USB_StatusInStage(); + break; + + case USB_REQUEST_GET_DESCRIPTOR: + if (!USB_ReqGetDescriptor()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_DESCRIPTOR: +/*stall_o:*/ USB_SetStallEP(0x00); /* not supported */ + EP0Data.Count = 0; + break; + + case USB_REQUEST_GET_CONFIGURATION: + if (!USB_ReqGetConfiguration()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_CONFIGURATION: + if (!USB_ReqSetConfiguration()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_CONFIGURE_EVENT + USB_Configure_Event(); +#endif + break; + + case USB_REQUEST_GET_INTERFACE: + if (!USB_ReqGetInterface()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_INTERFACE: + if (!USB_ReqSetInterface()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_INTERFACE_EVENT + USB_Interface_Event(); +#endif + break; + + default: + goto stall_i; + } + break; /* end case REQUEST_STANDARD */ + +#if USB_CLASS + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_GET_REPORT: + if (HID_GetReport()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_REPORT: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + case HID_REQUEST_GET_IDLE: + if (HID_GetIdle()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_IDLE: + if (HID_SetIdle()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case HID_REQUEST_GET_PROTOCOL: + if (HID_GetProtocol()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_PROTOCOL: + if (HID_SetProtocol()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_MSC + if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case MSC_REQUEST_RESET: + if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */ + (SetupPacket.wLength == 0)) { + if (MSC_Reset()) { + USB_StatusInStage(); + goto setup_class_ok; + } + } + break; + case MSC_REQUEST_GET_MAX_LUN: + if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */ + (SetupPacket.wLength == 1)) { + if (MSC_GetMaxLUN()) { + EP0Data.pData = EP0Buf; + USB_DataInStage(); + goto setup_class_ok; + } + } + break; + } + } +#endif /* USB_MSC */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_IF_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_ENCAPSULATED_RESPONSE: + if (CDC_GetEncapsulatedResponse()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_COMM_FEATURE: + if (CDC_GetCommFeature(SetupPacket.wValue.W)) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_CLEAR_COMM_FEATURE: + if (CDC_ClearCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SET_LINE_CODING: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_LINE_CODING: + if (CDC_GetLineCoding()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_CONTROL_LINE_STATE: + if (CDC_SetControlLineState(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SEND_BREAK: + if (CDC_SendBreak(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; /* not supported */ + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_EP_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +setup_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + if (SetupPacket.wLength) { + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); + } + } else { + USB_StatusInStage(); + } + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: +stall_i: USB_SetStallEP(0x80); + EP0Data.Count = 0; + break; + } + break; /* end case USB_EVT_SETUP */ + + case USB_EVT_OUT: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE) { + if (EP0Data.Count) { /* still data to receive ? */ + USB_DataOutStage(); /* receive data */ + if (EP0Data.Count == 0) { /* data complete ? */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + goto stall_i; /* not supported */ + +#if (USB_CLASS) + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_SET_REPORT: + if (HID_SetReport()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_IF_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + if (CDC_SendEncapsulatedCommand()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + if (CDC_SetCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_LINE_CODING: + if (CDC_SetLineCoding()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_EP_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +out_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + USB_StatusInStage(); + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + goto stall_i; + } + } + } + } else { + USB_StatusOutStage(); /* receive Acknowledge */ + } + break; /* end case USB_EVT_OUT */ + + case USB_EVT_IN : + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); /* send data */ + } else { + if (USB_DeviceAddress & 0x80) { + USB_DeviceAddress &= 0x7F; + USB_SetAddress(USB_DeviceAddress); + } + } + break; /* end case USB_EVT_IN */ + + case USB_EVT_OUT_STALL: + USB_ClrStallEP(0x00); + break; + + case USB_EVT_IN_STALL: + USB_ClrStallEP(0x80); + break; + + } +} diff --git a/core/usbcdc/usbcore.h b/core/usbcdc/usbcore.h new file mode 100644 index 0000000..9adee0f --- /dev/null +++ b/core/usbcdc/usbcore.h @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.h + * Purpose: USB Core Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + +#include "usbcfg.h" + +/* USB Endpoint Data Structure */ +typedef struct _USB_EP_DATA { + uint8_t *pData; + uint16_t Count; +} USB_EP_DATA; + +/* USB Core Global Variables */ +extern uint16_t USB_DeviceStatus; +extern uint8_t USB_DeviceAddress; +volatile extern uint8_t USB_Configuration; +extern uint32_t USB_EndPointMask; +extern uint32_t USB_EndPointHalt; +extern uint32_t USB_EndPointStall; +extern uint8_t USB_AltSetting[USB_IF_NUM]; + + +/* USB Endpoint 0 Buffer */ +extern uint8_t EP0Buf[USB_MAX_PACKET0]; + +/* USB Endpoint 0 Data Info */ +extern USB_EP_DATA EP0Data; + +/* USB Setup Packet */ +extern USB_SETUP_PACKET SetupPacket; + +/* USB Core Functions */ +extern void USB_ResetCore (void); + +/* Newer C compilers make it really difficult to add + * an integer to a pointer */ +static inline void UsbAddPtr(void **vpptr, uint32_t n); + +/* + * Add a number of bytes to a pointer's address + * Harder than you might think. Some compilers say: + * Expected an lvalue -- Assignment expects its first operand to be + * an lvalue. Please note that a cast removes the lvaluedness of an + * expression. + * + * vpptr = void pointer to pointer + * n = number of bytes to add to pointer + * Call looks like: AddPtr((void **)&myPointer, 8); + */ +static inline void UsbAddPtr(void **vpptr, uint32_t n) +{ + /* Declare a pointer to a pointer to a byte. Only a byte pointer + * can be incremented by a number of bytes. Other pointers will + * increment by a multiple of what they point to. + */ + uint8_t **bpptr; + + /* Convert our void pointer to a pointer to a byte pointer to a pointer */ + bpptr = (uint8_t **)vpptr; + + /* Add 'n' bytes to our pointer value */ + (*bpptr) += n; +} + + + + + + + +#endif /* __USBCORE_H__ */ diff --git a/core/usbcdc/usbdesc.c b/core/usbcdc/usbdesc.c new file mode 100644 index 0000000..e641ebd --- /dev/null +++ b/core/usbcdc/usbdesc.c @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.c + * Purpose: USB Descriptors + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Changed string descriptor handling + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ +#include "projectconfig.h" +#include "usb.h" +#include "cdc.h" +#include "usbcfg.h" +#include "usbdesc.h" +#include "config.h" + + +/* USB Standard Device Descriptor */ +const uint8_t USB_DeviceDescriptor[] = { + USB_DEVICE_DESC_SIZE, /* bLength */ + USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0200), /* 2.0 */ /* bcdUSB */ + USB_DEVICE_CLASS_COMMUNICATIONS, /* bDeviceClass CDC*/ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_PACKET0, /* bMaxPacketSize0 */ + WBVAL(USB_VENDOR_ID), /* idVendor */ + WBVAL(USB_PROD_ID), /* idProduct */ + WBVAL(USB_DEVICE), /* 1.00 */ /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01 /* bNumConfigurations: one possible configuration*/ +}; + +/* USB Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +const uint8_t USB_ConfigDescriptor[] = { +/* Configuration 1 */ + USB_CONFIGUARTION_DESC_SIZE, /* bLength */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL( /* wTotalLength */ + 1*USB_CONFIGUARTION_DESC_SIZE + + 1*USB_INTERFACE_DESC_SIZE + /* communication interface */ + 0x0013 + /* CDC functions */ + 1*USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */ + 1*USB_INTERFACE_DESC_SIZE + /* data interface */ + 2*USB_ENDPOINT_DESC_SIZE /* bulk endpoints */ + ), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ + 0x00, /* iConfiguration: no string to describe this configuration */ + USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ +/*USB_CONFIG_REMOTE_WAKEUP*/, + USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */ +/* Interface 0, Alternate Setting 0, Communication class interface descriptor */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */ + WBVAL(CDC_V1_10), /* 1.10 */ /* bcdCDC */ +/*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */ + 0x01, /* bmCapabilities: device handles call management */ + 0x01, /* bDataInterface: CDC data IF ID */ +/*Abstract Control Management Functional Descriptor*/ + 0x04, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */ +/*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_UNION, /* bDescriptorSubtype: Union func desc */ + USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */ + USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */ +/*Endpoint 1 Descriptor*/ /* event notification (optional) */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN(1), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ + WBVAL(0x0010), /* wMaxPacketSize */ + 0x02, /* 2ms */ /* bInterval */ +/* Interface 1, Alternate Setting 0, Data class interface descriptor*/ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: no alternate setting */ + 0x02, /* bNumEndpoints: two endpoints used */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */ + 0x00, /* bInterfaceSubClass: no subclass available */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/* Endpoint, EP3 Bulk Out */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_OUT(3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL(64), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Endpoint, EP3 Bulk In */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN(3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL(64), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Terminator */ + 0 /* bLength */ +}; + + + + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { +/* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0409), /* US English */ /* wLANGID */ +/* Index 0x01: Manufacturer */ + (13*2 + 2), /* bLength (13 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'M',0, + 'I',0, + 'C',0, + 'R',0, + 'O',0, + 'B',0, + 'U',0, + 'I',0, + 'L',0, + 'D',0, + 'E',0, + 'R',0, + ' ',0, +/* Index 0x02: Product */ + (17*2 + 2), /* bLength ( 17 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'L',0, + 'P',0, + 'C',0, + '1',0, + '3',0, + '4',0, + '3',0, + ' ',0, + 'C',0, + 'O',0, + 'M',0, + ' ',0, + 'P',0, + 'O',0, + 'R',0, + 'T',0, + ' ',0, +/* Index 0x03: Serial Number */ + (12*2 + 2), /* bLength (12 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'D',0, + 'E',0, + 'M',0, + 'O',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, +/* Index 0x04: Interface 0, Alternate Setting 0 */ + ( 4*2 + 2), /* bLength (4 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'V',0, + 'C',0, + 'O',0, + 'M',0, +}; diff --git a/core/usbcdc/usbdesc.h b/core/usbcdc/usbdesc.h new file mode 100644 index 0000000..9fd48e8 --- /dev/null +++ b/core/usbcdc/usbdesc.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.h + * Purpose: USB Descriptors Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBDESC_H__ +#define __USBDESC_H__ + + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_StringDescriptor[]; + + +#endif /* __USBDESC_H__ */ diff --git a/core/usbcdc/usbhw.c b/core/usbcdc/usbhw.c new file mode 100644 index 0000000..546a810 --- /dev/null +++ b/core/usbcdc/usbhw.c @@ -0,0 +1,606 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.c + * Purpose: USB Hardware Layer Module for Philips LPC17xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "projectconfig.h" /* LPC13xx definitions */ +#include "usb.h" +#include "usbcfg.h" +#include "usbreg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" + + +/* + * USB and IO Clock configuration only. + * The same as call PeriClkIOInit(IOCON_USB); + * The purpose is to reduce the code space for + * overall USB project and reserve code space for + * USB debugging. + * Parameters: None + * Return Value: None + */ +void USBIOClkConfig( void ) +{ + /* Enable AHB clock to the GPIO domain. */ + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_GPIO; + + /* Enable Timer32_1, IOCON, and USB blocks */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG); + + // Setup USB clock + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL + + SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; + + // Wait until the USB clock is updated + while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE)); + + // Set USB clock to 48MHz (12MHz x 4) + SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4); + while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked + SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT; + + // Set USB pin functions + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT + IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK; + IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus + IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK; + IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect + + return; +} + +/* + * Delay number of clock cycles + * Parameters: Delay length + * Return Value: None + */ + +void delay (uint32_t length ) +{ + uint32_t i; + + for ( i = 0; i < length; i++ ) + { + __asm("nop"); + } + return; +} + +/* + * Get Endpoint Physical Address + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Endpoint Physical Address + */ + +uint32_t EPAdr (uint32_t EPNum) +{ + uint32_t val; + + val = (EPNum & 0x0F) << 1; + if (EPNum & 0x80) { + val += 1; + } + return (val); +} + + +/* + * Write Command + * Parameters: cmd: Command + * Return Value: None + */ + +void WrCmd (uint32_t cmd) +{ + USB_DEVINTCLR = CCEMTY_INT; + USB_CMDCODE = cmd; + while ((USB_DEVINTST & (CCEMTY_INT | DEV_STAT_INT)) == 0); +} + + +/* + * Write Command Data + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void WrCmdDat (uint32_t cmd, uint32_t val) +{ + WrCmd(cmd); + WrCmd(val); +} + + +/* + * Write Command to Endpoint + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void WrCmdEP (uint32_t EPNum, uint32_t cmd) +{ + WrCmd(CMD_SEL_EP(EPAdr(EPNum))); + WrCmd(cmd); +} + + +/* + * Read Command Data + * Parameters: cmd: Command + * Return Value: Data Value + */ + +uint32_t RdCmdDat (uint32_t cmd) +{ + USB_DEVINTCLR = CCEMTY_INT | CDFULL_INT; + USB_CMDCODE = cmd; + while ((USB_DEVINTST & (CDFULL_INT | DEV_STAT_INT)) == 0); + return (USB_CMDDATA); +} + + +/* + * USB Initialize Function + * Called by the User to initialize USB + * Return Value: None + */ + +void USB_Init (void) +{ + // Setup USB clock and pins + USBIOClkConfig(); + +#if USB_FIQ_EVENT + /* It's important that only BULK and FRAME(ISO) can be routed + to FIQ. */ + USB_DEVFIQSEL = 0x01; /* SOF Use FIQ */ + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ(USB_FIQn); +#endif + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ(USB_IRQn); + + USB_Reset(); + USB_SetAddress(0); + return; +} + + +/* + * USB Connect Function + * Called by the User to Connect/Disconnect USB + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void USB_Connect (uint32_t con) +{ + WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0)); +} + + +/* + * USB Reset Function + * Called automatically on USB Reset + * Return Value: None + */ + +void USB_Reset (void) +{ + USB_DEVINTCLR = 0x000FFFFF; + /* Enable all eight(8) EPs, note: EP won't be ready until it's + configured/enabled when device sending SetEPStatus command + to the command engine. */ + USB_DEVINTEN = DEV_STAT_INT | (0xFF<<1) | + (USB_SOF_EVENT ? FRAME_INT : 0); + return; +} + + +/* + * USB Suspend Function + * Called automatically on USB Suspend + * Return Value: None + */ + +void USB_Suspend (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Resume Function + * Called automatically on USB Resume + * Return Value: None + */ + +void USB_Resume (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Remote Wakeup Function + * Called automatically on USB Remote Wakeup + * Return Value: None + */ + +void USB_WakeUp (void) +{ + if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) + { + WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); + } +} + + +/* + * USB Remote Wakeup Configuration Function + * Parameters: cfg: Enable/Disable + * Return Value: None + */ + +void USB_WakeUpCfg (uint32_t cfg) +{ + cfg = cfg; /* Not needed */ +} + + +/* + * USB Set Address Function + * Parameters: adr: USB Address + * Return Value: None + */ + +void USB_SetAddress (uint32_t adr) +{ + WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */ + WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */ +} + + +/* + * USB Configure Function + * Parameters: cfg: Configure/Deconfigure + * Return Value: None + */ + +void USB_Configure (uint32_t cfg) +{ + WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0)); + return; +} + + +/* + * Configure USB Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Endpoint Descriptor + * Return Value: None + */ + +void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) +{ + return; +} + + +/* + * Set Direction for USB Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void USB_DirCtrlEP (uint32_t dir) +{ + dir = dir; /* Not needed */ +} + + +/* + * Enable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_EnableEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Disable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_DisableEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA)); +} + + +/* + * Reset USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ResetEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Set Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_SetStallEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST)); +} + + +/* + * Clear Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ClrStallEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Clear USB Endpoint Buffer + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ClearEPBuf (uint32_t EPNum) +{ + WrCmdEP(EPNum, CMD_CLR_BUF); +} + + +/* + * Read USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData) +{ + uint32_t cnt, n; + + USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay( 5 ); + + do + { + cnt = USB_RXPLEN; + } while ((cnt & PKT_DV) == 0); + cnt &= PKT_LNGTH_MASK; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + *((uint32_t __attribute__((packed)) *)pData) = USB_RXDATA; + pData += 4; + } + + USB_CTRL = 0; + + if ((EPNum & 0x80) != 0x04) + { /* Non-Isochronous Endpoint */ + WrCmdEP(EPNum, CMD_CLR_BUF); + } + + return (cnt); +} + + +/* + * Write USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) +{ + uint32_t n; + + USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay( 5 ); + USB_TXPLEN = cnt; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData); + pData += 4; + } + + USB_CTRL = 0; + + WrCmdEP(EPNum, CMD_VALID_BUF); + + return (cnt); +} + +/* + * Get USB Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t USB_GetFrame (void) +{ + uint32_t val; + + WrCmd(CMD_RD_FRAME); + val = RdCmdDat(DAT_RD_FRAME); + val = val | (RdCmdDat(DAT_RD_FRAME) << 8); + + return (val); +} + + +/* + * USB Interrupt Service Routine + */ + +#ifdef CFG_USBCDC +void USB_IRQHandler (void) +{ + uint32_t disr, val, n, m; + + disr = USB_DEVINTST; /* Device Interrupt Status */ + USB_DEVINTCLR = disr; + + /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ + if (disr & DEV_STAT_INT) + { + WrCmd(CMD_GET_DEV_STAT); + val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */ + if (val & DEV_RST) { /* Reset */ + USB_Reset(); +#if USB_RESET_EVENT + USB_Reset_Event(); +#endif + } + if (val & DEV_CON_CH) { /* Connect change */ +#if USB_POWER_EVENT + USB_Power_Event(val & DEV_CON); +#endif + } + if (val & DEV_SUS_CH) { /* Suspend/Resume */ + if (val & DEV_SUS) { /* Suspend */ + USB_Suspend(); +#if USB_SUSPEND_EVENT + USB_Suspend_Event(); +#endif + } else { /* Resume */ + USB_Resume(); +#if USB_RESUME_EVENT + USB_Resume_Event(); +#endif + } + } + goto isr_end; + } + +#if USB_SOF_EVENT + /* Start of Frame Interrupt */ + if (disr & FRAME_INT) + { + USB_DEVINTCLR = FRAME_INT; + USB_SOF_Event(); + // SOFIRQCount++; + } +#endif + +#if USB_ERROR_EVENT + /* NO error interrupt anymore, below code can be used + as example to get error status from command engine. */ + /* Error Interrupt */ + if (disr & ERR_INT) + { + WrCmd(CMD_RD_ERR_STAT); + val = RdCmdDat(DAT_RD_ERR_STAT); + USB_Error_Event(val); + } +#endif + + /* Endpoint's Interrupt */ + if (disr & (0xFF<<1)) { + /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */ + for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */ + /* skip frame interrupt at bit 0 in disr */ +// if (disr & ((1 << n)<<1)) { + if ((disr>>1) & (1 << n)) { + m = n >> 1; + /* clear EP interrupt by sending cmd to the command engine. */ + WrCmd(CMD_SEL_EP_CLRI(n)); + val = RdCmdDat(DAT_SEL_EP_CLRI(n)); + if ((n & 1) == 0) { /* OUT Endpoint */ + if (n == 0) { /* Control OUT Endpoint */ + if (val & EP_SEL_STP) { /* Setup Packet */ + if (USB_P_EP[0]) { + USB_P_EP[0](USB_EVT_SETUP); + continue; + } + } + } + if (USB_P_EP[m]) { + USB_P_EP[m](USB_EVT_OUT); + } + } else { /* IN Endpoint */ + if (USB_P_EP[m]) { + USB_P_EP[m](USB_EVT_IN); + } + } + } + } + } +isr_end: + return; +} + +#endif diff --git a/core/usbcdc/usbhw.h b/core/usbcdc/usbhw.h new file mode 100644 index 0000000..e9ecb8d --- /dev/null +++ b/core/usbcdc/usbhw.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.h + * Purpose: USB Hardware Layer Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ + +#ifndef __USBHW_H__ +#define __USBHW_H__ + + +/* USB Error Codes */ +#define USB_ERR_PID 0x0001 /* PID Error */ +#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */ +#define USB_ERR_DCRC 0x0004 /* Data CRC Error */ +#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */ +#define USB_ERR_EOP 0x0010 /* End of Packet Error */ +#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */ +#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */ +#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */ + +/* USB Hardware Functions */ +extern void USBIOClkConfig (void); +extern void USB_Init (void); +extern void USB_Connect (uint32_t con); +extern void USB_Reset (void); +extern void USB_Suspend (void); +extern void USB_Resume (void); +extern void USB_WakeUp (void); +extern void USB_WakeUpCfg (uint32_t cfg); +extern void USB_SetAddress (uint32_t adr); +extern void USB_Configure (uint32_t cfg); +extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD); +extern void USB_DirCtrlEP (uint32_t dir); +extern void USB_EnableEP (uint32_t EPNum); +extern void USB_DisableEP (uint32_t EPNum); +extern void USB_ResetEP (uint32_t EPNum); +extern void USB_SetStallEP (uint32_t EPNum); +extern void USB_ClrStallEP (uint32_t EPNum); +extern void USB_ClearEPBuf (uint32_t EPNum); +extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData); +extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt); +extern uint32_t USB_GetFrame(void); +extern void USB_IRQHandler (void); + + +#endif /* __USBHW_H__ */ diff --git a/core/usbcdc/usbreg.h b/core/usbcdc/usbreg.h new file mode 100644 index 0000000..03240be --- /dev/null +++ b/core/usbcdc/usbreg.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBREG.H + * Purpose: USB Hardware Layer Definitions for NXP LPC13xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBREG_H +#define __USBREG_H + +/* Device Interrupt Bit Definitions */ +#define FRAME_INT (0x1<<0) +#define EP0_INT (0x1<<1) +#define EP1_INT (0x1<<2) +#define EP2_INT (0x1<<3) +#define EP3_INT (0x1<<4) +#define EP4_INT (0x1<<5) +#define EP5_INT (0x1<<6) +#define EP6_INT (0x1<<7) +#define EP7_INT (0x1<<8) +#define DEV_STAT_INT (0x1<<9) +#define CCEMTY_INT (0x1<<10) +#define CDFULL_INT (0x1<<11) +#define RxENDPKT_INT (0x1<<12) +#define TxENDPKT_INT (0x1<<13) + +/* Rx & Tx Packet Length Definitions */ +#define PKT_LNGTH_MASK 0x000003FF +#define PKT_DV 0x00000400 +#define PKT_RDY 0x00000800 + +/* USB Control Definitions */ +#define CTRL_RD_EN 0x00000001 +#define CTRL_WR_EN 0x00000002 + +/* Command Codes */ +#define CMD_SET_ADDR 0x00D00500 +#define CMD_CFG_DEV 0x00D80500 +#define CMD_SET_MODE 0x00F30500 +#define CMD_RD_INT 0x00F40500 +#define DAT_RD_INT 0x00F40200 +#define CMD_RD_FRAME 0x00F50500 +#define DAT_RD_FRAME 0x00F50200 +#define CMD_RD_CHIP_ID 0x00FD0500 +#define DAT_RD_CHIP_ID 0x00FD0200 + +#define CMD_SET_DEV_STAT 0x00FE0500 +#define CMD_GET_DEV_STAT 0x00FE0500 +#define DAT_GET_DEV_STAT 0x00FE0200 +#define CMD_GET_ERR_CODE 0x00FF0500 +#define DAT_GET_ERR_CODE 0x00FF0200 + +#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) +#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) +#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) +#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) +#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) +#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) +#define CMD_CLR_BUF 0x00F20500 +#define CMD_VALID_BUF 0x00FA0500 + +/* Device Address Register Definitions */ +#define DEV_ADDR_MASK 0x7F +#define DEV_EN 0x80 + +/* Device Configure Register Definitions */ +#define CONF_DVICE 0x01 + +/* Device Mode Register Definitions */ +#define AP_CLK 0x01 +#define INAK_CI 0x02 +#define INAK_CO 0x04 +#define INAK_AI 0x08 +#define INAK_AO 0x10 + +/* Device Status Register Definitions */ +#define DEV_CON 0x01 +#define DEV_CON_CH 0x02 +#define DEV_SUS 0x04 +#define DEV_SUS_CH 0x08 +#define DEV_RST 0x10 + +/* Error Code Register Definitions */ +#define ERR_EC_MASK 0x0F +#define ERR_EA 0x10 + +/* Error Status Register Definitions */ +#define ERR_NOERROR 0x00 +#define ERR_PID_ENCODE 0x01 +#define ERR_UNKNOWN_PID 0x02 +#define ERR_UNEXPECT_PKT 0x03 +#define ERR_TCRC 0x04 +#define ERR_DCRC 0x05 +#define ERR_TIMEOUT 0x06 +#define ERR_BABBIE 0x07 +#define ERR_EOF_PKT 0x08 +#define ERR_TX_RX_NAK 0x09 +#define ERR_SENT_STALL 0x0A +#define ERR_BUF_OVERRUN 0x0B +#define ERR_SENT_EPT_PKT 0x0C +#define ERR_BIT_STUFF 0x0D +#define ERR_SYNC 0x0E +#define ERR_TOGGLE_BIT 0x0F + +/* Endpoint Select Register Definitions */ +#define EP_SEL_F 0x01 +#define EP_SEL_ST 0x02 +#define EP_SEL_STP 0x04 +#define EP_SEL_PO 0x08 +#define EP_SEL_EPN 0x10 +#define EP_SEL_B_1_FULL 0x20 +#define EP_SEL_B_2_FULL 0x40 + +/* Endpoint Status Register Definitions */ +#define EP_STAT_ST 0x01 +#define EP_STAT_DA 0x20 +#define EP_STAT_RF_MO 0x40 +#define EP_STAT_CND_ST 0x80 + +/* Clear Buffer Register Definitions */ +#define CLR_BUF_PO 0x01 + +#endif /* __USBREG_H */ diff --git a/core/usbcdc/usbuser.c b/core/usbcdc/usbuser.c new file mode 100644 index 0000000..a67eeb8 --- /dev/null +++ b/core/usbcdc/usbuser.c @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbuser.c + * Purpose: USB Custom User Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ +#include "projectconfig.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" +#include "cdcuser.h" + + +/* + * USB Power Event Callback + * Called automatically on USB Power Event + * Parameter: power: On(TRUE)/Off(FALSE) + */ + +#if USB_POWER_EVENT +void USB_Power_Event (uint32_t power) { +} +#endif + + +/* + * USB Reset Event Callback + * Called automatically on USB Reset Event + */ + +#if USB_RESET_EVENT +void USB_Reset_Event (void) { + USB_ResetCore(); +} +#endif + + +/* + * USB Suspend Event Callback + * Called automatically on USB Suspend Event + */ + +#if USB_SUSPEND_EVENT +void USB_Suspend_Event (void) { +} +#endif + + +/* + * USB Resume Event Callback + * Called automatically on USB Resume Event + */ + +#if USB_RESUME_EVENT +void USB_Resume_Event (void) { +} +#endif + + +/* + * USB Remote Wakeup Event Callback + * Called automatically on USB Remote Wakeup Event + */ + +#if USB_WAKEUP_EVENT +void USB_WakeUp_Event (void) { +} +#endif + + +/* + * USB Start of Frame Event Callback + * Called automatically on USB Start of Frame Event + */ + +#if USB_SOF_EVENT +void USB_SOF_Event (void) { +} +#endif + + +/* + * USB Error Event Callback + * Called automatically on USB Error Event + * Parameter: error: Error Code + */ + +#if USB_ERROR_EVENT +void USB_Error_Event (uint32_t error) { +} +#endif + + +/* + * USB Set Configuration Event Callback + * Called automatically on USB Set Configuration Request + */ + +#if USB_CONFIGURE_EVENT +void USB_Configure_Event (void) { + + if (USB_Configuration) { /* Check if USB is configured */ + /* add your code here */ + } +} +#endif + + +/* + * USB Set Interface Event Callback + * Called automatically on USB Set Interface Request + */ + +#if USB_INTERFACE_EVENT +void USB_Interface_Event (void) { +} +#endif + + +/* + * USB Set/Clear Feature Event Callback + * Called automatically on USB Set/Clear Feature Request + */ + +#if USB_FEATURE_EVENT +void USB_Feature_Event (void) { +} +#endif + + +#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL) + +/* USB Endpoint Events Callback Pointers */ +void (* const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = { + P_EP(0), + P_EP(1), + P_EP(2), + P_EP(3), + P_EP(4), +}; + + +/* + * USB Endpoint 1 Event Callback + * Called automatically on USB Endpoint 1 Event + * Parameter: event + */ + +void USB_EndPoint1 (uint32_t event) { + uint16_t temp; + static uint16_t serialState; + + switch (event) { + case USB_EVT_IN: + temp = CDC_GetSerialState(); + if (serialState != temp) { + serialState = temp; + CDC_NotificationIn(); /* send SERIAL_STATE notification */ + } + break; + } +} + + +/* + * USB Endpoint 2 Event Callback + * Called automatically on USB Endpoint 2 Event + * Parameter: event + */ + +void USB_EndPoint2 (uint32_t event) +{ + event = event; +} + + +/* + * USB Endpoint 3 Event Callback + * Called automatically on USB Endpoint 3 Event + * Parameter: event + */ + +void USB_EndPoint3 (uint32_t event) { + switch (event) { + case USB_EVT_OUT: + CDC_BulkOut (); /* data received from Host */ + break; + case USB_EVT_IN: + CDC_BulkIn (); /* data expected from Host */ + break; + } +} + + diff --git a/core/usbcdc/usbuser.h b/core/usbcdc/usbuser.h new file mode 100644 index 0000000..10b33ad --- /dev/null +++ b/core/usbcdc/usbuser.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBUSER.H + * Purpose: USB Custom User Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2005-2009 Keil Software. + *---------------------------------------------------------------------------*/ + +#ifndef __USBUSER_H__ +#define __USBUSER_H__ + + +/* USB Device Events Callback Functions */ +extern void USB_Power_Event (uint32_t power); +extern void USB_Reset_Event (void); +extern void USB_Suspend_Event (void); +extern void USB_Resume_Event (void); +extern void USB_WakeUp_Event (void); +extern void USB_SOF_Event (void); +extern void USB_Error_Event (uint32_t error); + +/* USB Endpoint Callback Events */ +#define USB_EVT_SETUP 1 /* Setup Packet */ +#define USB_EVT_OUT 2 /* OUT Packet */ +#define USB_EVT_IN 3 /* IN Packet */ +#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */ +#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */ +#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */ +#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */ + +/* USB Endpoint Events Callback Pointers */ +extern void (* const USB_P_EP[USB_LOGIC_EP_NUM])(uint32_t event); + +/* USB Endpoint Events Callback Functions */ +extern void USB_EndPoint0 (uint32_t event); +extern void USB_EndPoint1 (uint32_t event); +extern void USB_EndPoint2 (uint32_t event); +extern void USB_EndPoint3 (uint32_t event); +extern void USB_EndPoint4 (uint32_t event); + +/* USB Core Events Callback Functions */ +extern void USB_Configure_Event (void); +extern void USB_Interface_Event (void); +extern void USB_Feature_Event (void); + + +#endif /* __USBUSER_H__ */ diff --git a/core/usbhid-rom/usb.h b/core/usbhid-rom/usb.h new file mode 100644 index 0000000..2e55b8c --- /dev/null +++ b/core/usbhid-rom/usb.h @@ -0,0 +1,240 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USB_H__ +#define __USB_H__ + +#include "sysdefs.h" + +typedef union +{ + uint16_t W; + struct + { + uint8_t L; + uint8_t H; + } __attribute__ ((packed)) WB; +} __attribute__ ((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE +{ + struct _BM + { + uint8_t Recipient : 5; + uint8_t Type : 2; + uint8_t Dir : 1; + } __attribute__ ((packed)) BM; + uint8_t B; +} __attribute__ ((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__ ((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString/*[]*/; +} __attribute__ ((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR; + +#endif diff --git a/core/usbhid-rom/usbconfig.c b/core/usbhid-rom/usbconfig.c new file mode 100644 index 0000000..6fa0a7f --- /dev/null +++ b/core/usbhid-rom/usbconfig.c @@ -0,0 +1,115 @@ +/**************************************************************************/ +/*! + @file usbconfig.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "usb.h" +#include "usbconfig.h" + +#ifndef WBVAL +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) +#endif + +/* USB String Descriptor (optional) */ +const uint8_t USB_HIDStringDescriptor[] = +{ + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0409), /* US English */ /* wLANGID */ + /* Index 0x04: Manufacturer */ + 0x1C, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'm',0, + 'i',0, + 'c',0, + 'r',0, + 'o',0, + 'B',0, + 'u',0, + 'i',0, + 'l',0, + 'd',0, + 'e',0, + 'r',0, + ' ',0, + /* Index 0x20: Product */ + 0x28, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'L',0, + 'P',0, + 'C',0, + '1',0, + '3',0, + '4',0, + '3',0, + ' ',0, + 'R',0, + 'e',0, + 'f',0, + '.',0, + ' ',0, + 'B',0, + 'o',0, + 'a',0, + 'r',0, + 'd',0, + ' ',0, + /* Index 0x48: Serial Number */ + 0x1A, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + /* Index 0x62: Interface 0, Alternate Setting 0 */ + 0x0E, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'H',0, + 'I',0, + 'D',0, + ' ',0, + ' ',0, + ' ',0, +}; diff --git a/core/usbhid-rom/usbconfig.h b/core/usbhid-rom/usbconfig.h new file mode 100644 index 0000000..6a6db5a --- /dev/null +++ b/core/usbhid-rom/usbconfig.h @@ -0,0 +1,66 @@ +/**************************************************************************/ +/*! + @file usbconfig.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _USBCONFIG_H_ +#define _USBCONFIG_H_ + +#include "projectconfig.h" + +#define USB_VENDOR_ID CFG_USB_VID // Vendor ID +#define USB_PROD_ID CFG_USB_PID // Product ID +#define USB_DEVICE 0x0100 // Device ID + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +#define HID_DESC_OFFSET 0x0012 +#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR)) +#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_HIDStringDescriptor[]; + +extern const uint8_t HID_ReportDescriptor[]; +extern const uint16_t HID_ReportDescSize; + +#endif \ No newline at end of file diff --git a/core/usbhid-rom/usbhid.c b/core/usbhid-rom/usbhid.c new file mode 100644 index 0000000..3f27135 --- /dev/null +++ b/core/usbhid-rom/usbhid.c @@ -0,0 +1,222 @@ +/**************************************************************************/ +/*! + @file usbhid.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "core/usbhid-rom/usb.h" +#include "core/usbhid-rom/usbconfig.h" +#include "core/rom_drivers.h" +#include "core/gpio/gpio.h" +#include "core/adc/adc.h" +#include "core/systick/systick.h" + +#include "usbhid.h" + +USB_DEV_INFO DeviceInfo; +HID_DEVICE_INFO HidDevInfo; +ROM ** rom = (ROM **)0x1fff1ff8; + +typedef struct usbhid_out_s +{ + uint16_t gpio1Dir; + uint16_t gpio1Data; + uint16_t gpio2Dir; + uint16_t gpio2Data; + uint16_t gpio3Dir; + uint16_t gpio3Data; + uint16_t adc0; + uint16_t adc1; + uint16_t adc2; + uint16_t adc3; + uint32_t systicks; + uint32_t rollovers; +} usbhid_out_t; + +/**************************************************************************/ +/*! + @brief Gets the HID In Report (the report going from the LPC1343 to + the USB host) +*/ +/**************************************************************************/ +void usbHIDGetInReport (uint8_t src[], uint32_t length) +{ + usbhid_out_t out; + + out.gpio1Dir = GPIO_GPIO1DIR; + out.gpio1Data = GPIO_GPIO1DATA; + out.gpio2Dir = GPIO_GPIO2DIR; + out.gpio2Data = GPIO_GPIO2DATA; + out.gpio3Dir = GPIO_GPIO3DIR; + out.gpio3Data = GPIO_GPIO3DATA; + out.adc0 = adcRead(0); + out.adc1 = adcRead(1); + out.adc2 = adcRead(2); + out.adc3 = adcRead(3); + out.systicks = systickGetTicks(); + out.rollovers = systickGetRollovers(); + + size_t i = 0; + memcpy(&src[i], &out.gpio1Dir, sizeof out.gpio1Dir); + i += sizeof out.gpio1Dir; + memcpy(&src[i], &out.gpio1Data, sizeof out.gpio1Data); + i += sizeof out.gpio1Data; + memcpy(&src[i], &out.gpio2Dir, sizeof out.gpio2Dir); + i += sizeof out.gpio2Dir; + memcpy(&src[i], &out.gpio2Data, sizeof out.gpio2Data); + i += sizeof out.gpio2Data; + memcpy(&src[i], &out.gpio3Dir, sizeof out.gpio3Dir); + i += sizeof out.gpio3Dir; + memcpy(&src[i], &out.gpio3Data, sizeof out.gpio3Data); + i += sizeof out.gpio3Data; + memcpy(&src[i], &out.adc0, sizeof out.adc0); + i += sizeof out.adc0; + memcpy(&src[i], &out.adc1, sizeof out.adc1); + i += sizeof out.adc1; + memcpy(&src[i], &out.adc2, sizeof out.adc2); + i += sizeof out.adc2; + memcpy(&src[i], &out.adc3, sizeof out.adc3); + i += sizeof out.adc3; + memcpy(&src[i], &out.systicks, sizeof out.systicks); + i += sizeof out.systicks; + memcpy(&src[i], &out.rollovers, sizeof out.rollovers); + i += sizeof out.rollovers; +} + +/**************************************************************************/ +/*! + @brief Sets the HID Out Report (the report coming in from the USB + host to the LPC1343). +*/ +/**************************************************************************/ +void usbHIDSetOutReport (uint8_t dst[], uint32_t length) +{ + uint8_t PCOutReportData = dst[0]; + // Check bit 0 in the incoming report to determine is LED should + // be enabled or disabled (1 = enabled, 0 = disabled) + if (PCOutReportData & (1<<0)) + { + // Enable LED (set low) + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 0); + } + else + { + // Disable LED (set high) + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 1); + } +} + +/**************************************************************************/ +/*! + @brief Initialises the USB port + + The ROM-based USB HID code is capable of configuring the PLL and pins + for USB, but there seems to be a bug in the code that sets the system + clock to 48MHz (normally the USB and System clocks can be configured + seperately). As such, this code does not use the "init_clk_pins()" + function in the rom, and the USB clock and pins are manually + configured. +*/ +/**************************************************************************/ +void usbHIDInit (void) +{ + // Setup USB clock + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL + + SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; + + // Wait until the USB clock is updated + while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE)); + + // Set USB clock to 48MHz (12MHz x 4) + SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4); + while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked + SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT; + + // Set USB pin functions + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT + IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK; + IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus + IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK; + IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect + + // Disable internal resistor on VBUS (0.3) + gpioSetPullup(&IOCON_PIO0_3, gpioPullupMode_Inactive); + + // HID Device Info + volatile int n; + HidDevInfo.idVendor = USB_VENDOR_ID; + HidDevInfo.idProduct = USB_PROD_ID; + HidDevInfo.bcdDevice = USB_DEVICE; + HidDevInfo.StrDescPtr = (uint32_t)&USB_HIDStringDescriptor[0]; + HidDevInfo.InReportCount = sizeof(usbhid_out_t); + HidDevInfo.OutReportCount = 1; + HidDevInfo.SampleInterval = 0x20; + HidDevInfo.InReport = usbHIDGetInReport; + HidDevInfo.OutReport = usbHIDSetOutReport; + + DeviceInfo.DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE; + DeviceInfo.DevDetailPtr = (uint32_t)&HidDevInfo; + + /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG); + + /* Use pll and pin init function in rom */ + /* Warning: This will also set the system clock to 48MHz! */ + // (*rom)->pUSBD->init_clk_pins(); + + /* insert a delay between clk init and usb init */ + for (n = 0; n < 75; n++) {__asm("nop");} + + (*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */ + (*rom)->pUSBD->connect(true); /* USB Connect */ +} + +/**************************************************************************/ +/*! + @brief Passes the USB interrupt to the internal ROM-based handler +*/ +/**************************************************************************/ +#ifdef CFG_USBHID +void USB_IRQHandler() +{ + (*rom)->pUSBD->isr(); +} +#endif + diff --git a/core/usbhid-rom/usbhid.h b/core/usbhid-rom/usbhid.h new file mode 100644 index 0000000..d1f0152 --- /dev/null +++ b/core/usbhid-rom/usbhid.h @@ -0,0 +1,46 @@ +/**************************************************************************/ +/*! + @file usbhid.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _USBCONFIG_H_ +#define _USBCONFIG_H_ + +#include "projectconfig.h" + +void usbHIDGetInReport (uint8_t src[], uint32_t length); +void usbHIDSetOutReport (uint8_t dst[], uint32_t length); +void usbHIDInit (void); + +#endif diff --git a/core/wdt/wdt.c b/core/wdt/wdt.c new file mode 100644 index 0000000..c91ffca --- /dev/null +++ b/core/wdt/wdt.c @@ -0,0 +1,152 @@ +/**************************************************************************/ +/*! + @file wdt.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Sets up the watchdog timer (WDT). The WDT allows you to monitor + whether the device is still executing properly. If the watchdog + isn't 'fed' within a pre-determined delay, it will raise an interrupt + allowing you to decide if you want to reset the device, etc. + + @code + #include "core/cpu/cpu.h" + #include "core/wdt/wdt.h" + ... + cpuInit(); + + // Initialise wdt with no reset on timeout + wdtInit(false); + + // Pat the watchdog (to start the timer) + wdtFeed(); + + while (1) + { + // Keep the watchdog happy by regularly feeding it + wdtFeed(); + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "wdt.h" + +#define WDT_FEED_VALUE (0x003FFFFF) + +volatile uint32_t wdt_counter; + +/**************************************************************************/ +/*! + IRQ Handler when the watchdog times out. Any actions that you wish + to take when a timeout occurs should be called from here. +*/ +/**************************************************************************/ +void WDT_IRQHandler(void) +{ + /* Clear the time-out interrupt flag */ + WDT_WDMOD &= ~WDT_WDMOD_WDTOF; + wdt_counter++; +} + +/**************************************************************************/ +/*! + Setup the clock for the watchdog timer. The default setting is 250kHz. +*/ +/**************************************************************************/ +static void wdtClockSetup (void) +{ + /* Watchdog Configuration */ + /* Freq. = 0.5MHz, div = 2: WDT_OSC = 250kHz */ + SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ | + SCB_WDTOSCCTRL_DIVSEL_DIV2; + + /* Set clock source (use WDT oscillator) */ + SCB_WDTCLKSEL = SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_DISABLE; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE; + + /* Wait until updated */ + while (!(SCB_WDTCLKUEN & SCB_WDTCLKUEN_UPDATE)); + + /* Set divider */ + SCB_WDTCLKDIV = SCB_WDTCLKDIV_DIV1; + + /* Enable WDT clock */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC); +} + +/**************************************************************************/ +/*! + Initialises the watchdog timer and sets up the interrupt. +*/ +/**************************************************************************/ +void wdtInit (bool reset) +{ + /* Setup the WDT clock */ + wdtClockSetup(); + + /* Enable AHB clock to the WDT domain. */ + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_WDT; + + wdt_counter = 0; + + /* Enable the WDT interrupt */ + NVIC_EnableIRQ(WDT_IRQn); + + /* Set timeout value (must be at least 0x000000FF) */ + WDT_WDTC = WDT_FEED_VALUE; + + /* Enable the watchdog timer (without system reset) */ + WDT_WDMOD = WDT_WDMOD_WDEN_ENABLED | + reset ? WDT_WDMOD_WDRESET_ENABLED : WDT_WDMOD_WDRESET_DISABLED ; +} + +/**************************************************************************/ +/*! + Feeds the watchdog to keep it from timing out. Interrupts will be + disabled while feeding the watchdog. +*/ +/**************************************************************************/ +void wdtFeed (void) +{ + /* Pet the watchdog */ + __disable_irq(); + WDT_WDFEED = WDT_WDFEED_FEED1; + WDT_WDFEED = WDT_WDFEED_FEED2; + __enable_irq(); +} + diff --git a/core/wdt/wdt.h b/core/wdt/wdt.h new file mode 100644 index 0000000..9238680 --- /dev/null +++ b/core/wdt/wdt.h @@ -0,0 +1,47 @@ +/**************************************************************************/ +/*! + @file wdt.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _WDT_H_ +#define _WDT_H_ + +#include "projectconfig.h" + +void wdtInit (bool reset); +void wdtFeed (void); + +#endif \ No newline at end of file diff --git a/lpc1xxx/LPC11xx_handlers.c b/lpc1xxx/LPC11xx_handlers.c new file mode 100644 index 0000000..2f713e2 --- /dev/null +++ b/lpc1xxx/LPC11xx_handlers.c @@ -0,0 +1,170 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// The GCC compiler defines the current architecture derived from the -mcpu argument. +// When target cpu is the cortex-m0, it automatically defines __ARM_ARCH_6M__ +#ifndef __ARM_ARCH_6M__ + #error "The target ARM cpu must be Cortex-M0 compatible (-mcpu=cortex-m0)" +#endif + +// Declare a weak alias macro as described in the GCC manual[1][2] +#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f))); +#define SECTION(s) __attribute__ ((section(s))) + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +void irq_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void CAN_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined); +void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined); + +/***************************************************************************** + * Forward undefined fault handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + ****************************************************************************/ + +void fault_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void NMI_Handler(void) WEAK_ALIAS(fault_undefined); +void HardFault_Handler(void) WEAK_ALIAS(fault_undefined); +void MemManage_Handler(void) WEAK_ALIAS(fault_undefined); +void BusFault_Handler(void) WEAK_ALIAS(fault_undefined); +void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined); +void SVCall_Handler(void) WEAK_ALIAS(fault_undefined); +void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined); +void PendSV_Handler(void) WEAK_ALIAS(fault_undefined); +void SysTick_Handler(void) WEAK_ALIAS(fault_undefined); + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +// Prototype the entry values, which are handled by the linker script +extern void* stack_entry; +extern void boot_entry(void); + +// Defined irq vectors using simple c code following the description in a white +// paper from ARM[3] and code example from Simonsson Fun Technologies[4]. +// These vectors are placed at the memory location defined in the linker script +const void *vectors[] SECTION(".irq_vectors") = +{ + // Stack and program reset entry point + &stack_entry, // The initial stack pointer + boot_entry, // The reset handler + + // Various fault handlers + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // MemManage_Handler + BusFault_Handler, // BusFault_Handler + UsageFault_Handler, // UsageFault_Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVCall_Handler, // SVCall handler + DebugMon_Handler, // DebugMon_Handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Wakeup I/O pins handlers + WAKEUP_IRQHandler, // PIO0_0 Wakeup + WAKEUP_IRQHandler, // PIO0_1 Wakeup + WAKEUP_IRQHandler, // PIO0_2 Wakeup + WAKEUP_IRQHandler, // PIO0_3 Wakeup + WAKEUP_IRQHandler, // PIO0_4 Wakeup + WAKEUP_IRQHandler, // PIO0_5 Wakeup + WAKEUP_IRQHandler, // PIO0_6 Wakeup + WAKEUP_IRQHandler, // PIO0_7 Wakeup + WAKEUP_IRQHandler, // PIO0_8 Wakeup + WAKEUP_IRQHandler, // PIO0_9 Wakeup + WAKEUP_IRQHandler, // PIO0_10 Wakeup + WAKEUP_IRQHandler, // PIO0_11 Wakeup + WAKEUP_IRQHandler, // PIO1_0 Wakeup + + // Specific peripheral irq handlers + CAN_IRQHandler, // CAN + SSP1_IRQHandler, // SSP1 + I2C_IRQHandler, // I2C0 + TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0) + TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1) + TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0) + TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1) + SSP0_IRQHandler, // SSP0 + UART_IRQHandler, // UART0 + USB_IRQHandler, // USB IRQ + USB_FIQHandler, // USB FIQ + ADC_IRQHandler, // ADC (A/D Converter) + WDT_IRQHandler, // WDT (Watchdog Timer) + BOD_IRQHandler, // BOD (Brownout Detect) + FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller) + PIOINT3_IRQHandler, // PIO INT3 + PIOINT2_IRQHandler, // PIO INT2 + PIOINT1_IRQHandler, // PIO INT1 + PIOINT0_IRQHandler, // PIO INT0 +}; + +/****************************************************************************** + * References + * [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html + * [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf + * [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php + *****************************************************************************/ + diff --git a/lpc1xxx/LPC13xx_handlers.c b/lpc1xxx/LPC13xx_handlers.c new file mode 100644 index 0000000..7fe40c4 --- /dev/null +++ b/lpc1xxx/LPC13xx_handlers.c @@ -0,0 +1,193 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// The GCC compiler defines the current architecture derived from the -mcpu argument. +// When target cpu is the cortex-m3, it automatically defines __ARM_ARCH_7M__ +#ifndef __ARM_ARCH_7M__ + #error "The target ARM cpu must be Cortex-M3 compatible (-mcpu=cortex-m3)" +#endif + +// Declare a weak alias macro as described in the GCC manual[1][2] +#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f))); +#define SECTION(s) __attribute__ ((section(s))) + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +void irq_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined); +void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined); + +/***************************************************************************** + * Forward undefined fault handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + ****************************************************************************/ + +void fault_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void NMI_Handler(void) WEAK_ALIAS(fault_undefined); +void HardFault_Handler(void) WEAK_ALIAS(fault_undefined); +void MemManage_Handler(void) WEAK_ALIAS(fault_undefined); +void BusFault_Handler(void) WEAK_ALIAS(fault_undefined); +void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined); +void SVCall_Handler(void) WEAK_ALIAS(fault_undefined); +void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined); +void PendSV_Handler(void) WEAK_ALIAS(fault_undefined); +void SysTick_Handler(void) WEAK_ALIAS(fault_undefined); + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +// Prototype the entry values, which are handled by the linker script +extern void* stack_entry; +extern void boot_entry(void); + +// Defined irq vectors using simple c code following the description in a white +// paper from ARM[3] and code example from Simonsson Fun Technologies[4]. +// These vectors are placed at the memory location defined in the linker script +const void *vectors[] SECTION(".irq_vectors") = +{ + // Stack and program reset entry point + &stack_entry, // The initial stack pointer + boot_entry, // The reset handler + + // Various fault handlers + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVCall_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Wakeup I/O pins handlers + WAKEUP_IRQHandler, // PIO0_0 Wakeup + WAKEUP_IRQHandler, // PIO0_1 Wakeup + WAKEUP_IRQHandler, // PIO0_2 Wakeup + WAKEUP_IRQHandler, // PIO0_3 Wakeup + WAKEUP_IRQHandler, // PIO0_4 Wakeup + WAKEUP_IRQHandler, // PIO0_5 Wakeup + WAKEUP_IRQHandler, // PIO0_6 Wakeup + WAKEUP_IRQHandler, // PIO0_7 Wakeup + WAKEUP_IRQHandler, // PIO0_8 Wakeup + WAKEUP_IRQHandler, // PIO0_9 Wakeup + WAKEUP_IRQHandler, // PIO0_10 Wakeup + WAKEUP_IRQHandler, // PIO0_11 Wakeup + WAKEUP_IRQHandler, // PIO1_0 Wakeup + WAKEUP_IRQHandler, // PIO1_1 Wakeup + WAKEUP_IRQHandler, // PIO1_2 Wakeup + WAKEUP_IRQHandler, // PIO1_3 Wakeup + WAKEUP_IRQHandler, // PIO1_4 Wakeup + WAKEUP_IRQHandler, // PIO1_5 Wakeup + WAKEUP_IRQHandler, // PIO1_6 Wakeup + WAKEUP_IRQHandler, // PIO1_7 Wakeup + WAKEUP_IRQHandler, // PIO1_8 Wakeup + WAKEUP_IRQHandler, // PIO1_9 Wakeup + WAKEUP_IRQHandler, // PIO1_10 Wakeup + WAKEUP_IRQHandler, // PIO1_11 Wakeup + WAKEUP_IRQHandler, // PIO2_0 Wakeup + WAKEUP_IRQHandler, // PIO2_1 Wakeup + WAKEUP_IRQHandler, // PIO2_2 Wakeup + WAKEUP_IRQHandler, // PIO2_3 Wakeup + WAKEUP_IRQHandler, // PIO2_4 Wakeup + WAKEUP_IRQHandler, // PIO2_5 Wakeup + WAKEUP_IRQHandler, // PIO2_6 Wakeup + WAKEUP_IRQHandler, // PIO2_7 Wakeup + WAKEUP_IRQHandler, // PIO2_8 Wakeup + WAKEUP_IRQHandler, // PIO2_9 Wakeup + WAKEUP_IRQHandler, // PIO2_10 Wakeup + WAKEUP_IRQHandler, // PIO2_11 Wakeup + WAKEUP_IRQHandler, // PIO3_0 Wakeup + WAKEUP_IRQHandler, // PIO3_1 Wakeup + WAKEUP_IRQHandler, // PIO3_2 Wakeup + WAKEUP_IRQHandler, // PIO3_3 Wakeup + + // Specific peripheral irq handlers + I2C_IRQHandler, // I2C0 + TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0) + TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1) + TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0) + TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1) + SSP_IRQHandler, // SSP0 + UART_IRQHandler, // UART0 + USB_IRQHandler, // USB IRQ + USB_FIQHandler, // USB FIQ + ADC_IRQHandler, // ADC (A/D Converter) + WDT_IRQHandler, // WDT (Watchdog Timer) + BOD_IRQHandler, // BOD (Brownout Detect) + FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller) + PIOINT3_IRQHandler, // PIO INT3 + PIOINT2_IRQHandler, // PIO INT2 + PIOINT1_IRQHandler, // PIO INT1 + PIOINT0_IRQHandler, // PIO INT0 +}; + +/****************************************************************************** + * References + * [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html + * [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf + * [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php + *****************************************************************************/ + diff --git a/lpc1xxx/LPC1xxx_startup.c b/lpc1xxx/LPC1xxx_startup.c new file mode 100644 index 0000000..db54ec3 --- /dev/null +++ b/lpc1xxx/LPC1xxx_startup.c @@ -0,0 +1,65 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// These are defined and created by the linker, locating them in memory +extern unsigned char _etext; +extern unsigned char _data; +extern unsigned char _edata; +extern unsigned char _bss; +extern unsigned char _ebss; + +// Prototype the required startup functions +extern void main(void); + +// The entry point of the application, prepare segments, +// initialize the cpu and execute main() +void boot_entry(void) +{ + register unsigned char *src, *dst; + + // Get physical data address and copy it to sram + src = &_etext; + dst = &_data; + while(dst < &_edata) { + *dst++ = *src++; + } + + // Clear the bss segment + dst = &_bss; + while(dst < &_ebss) { + *dst++ = 0; + } + + // Execute the code at the program entry point + main(); + + // Do nothing when returned from main, just keep looping + while(1); +} diff --git a/lpc1xxx/linkscript.ld b/lpc1xxx/linkscript.ld new file mode 100644 index 0000000..b6598f6 --- /dev/null +++ b/lpc1xxx/linkscript.ld @@ -0,0 +1,77 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +sram_top = ORIGIN(sram) + LENGTH(sram); +ENTRY(boot_entry) + +SECTIONS +{ + .text : + { + KEEP(*(.irq_vectors)) + *(.text*) + *(.rodata*) + } > flash + + /* + * More information about Special Section Indexes is available in the + * free "ELF for the ARM Architecture" document from ARM Limited + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf + * + */ + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > flash + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > flash + __exidx_end = .; + + _etext = .; + + .data : AT (__exidx_end) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > sram + + /* zero initialized data */ + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > sram + + end = .; + + /* For GDB compatibility we decrease the top with 16 bytes */ + stack_entry = sram_top - 16; +} diff --git a/sysdefs.h b/sysdefs.h new file mode 100644 index 0000000..bf79c8e --- /dev/null +++ b/sysdefs.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/*! + @file sysdefs.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SYSDEFS_H_ +#define _SYSDEFS_H_ + +#include +#include +#include + +// Stay compatible with ugly "windows" style +#define BOOL bool +#define TRUE true +#define FALSE false + +typedef volatile uint8_t REG8; +typedef volatile uint16_t REG16; +typedef volatile uint32_t REG32; +typedef unsigned char byte_t; + +#define pREG8 (REG8 *) +#define pREG16 (REG16 *) +#define pREG32 (REG32 *) + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#endif + diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..6957146 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,12 @@ +CC = gcc +LD = gcc +LDFLAGS = -Wall -O4 -std=c99 +EXES = lpcrc + +all: $(EXES) + +% : %.c + $(LD) $(LDFLAGS) -o $@ $< + +clean: + rm -f $(EXES) diff --git a/tools/lpcrc.c b/tools/lpcrc.c new file mode 100644 index 0000000..e811c45 --- /dev/null +++ b/tools/lpcrc.c @@ -0,0 +1,97 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#define BLOCK_COUNT 7 +#define BLOCK_LENGTH 4 +#define BLOCK_TOTAL (BLOCK_COUNT*BLOCK_LENGTH) + +typedef unsigned char byte_t; + +int main(int argc, char *argv[]) +{ + FILE* pf; + byte_t buf[BLOCK_TOTAL]; + uint32_t crc = 0; + uint32_t block; + + // Check for required arguments + if (argc < 2) + { + printf("syntax: lpcrc \n"); + return 1; + } + + // Try to open the supplied firmware + if ((pf = fopen(argv[1],"rb+")) == NULL) + { + printf("error: could not open file [%s] with write access\n",argv[1]); + return 1; + } + + // Read out the data blocks used for crc calculation + if (fread(buf,1,BLOCK_TOTAL,pf) != BLOCK_TOTAL) + { + printf("error: could not read required bytes\n"); + fclose(pf); + return 1; + } + + // Compute the crc value + for (block=0; block