diff --git a/.gitignore b/.gitignore index ca1dbd7..596c3ef 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ *.out *.app /Debug/ +/.metadata/ diff --git a/.mcuxpressoide_packages_support/crt_directory.xml b/.mcuxpressoide_packages_support/crt_directory.xml new file mode 100644 index 0000000..3102557 --- /dev/null +++ b/.mcuxpressoide_packages_support/crt_directory.xml @@ -0,0 +1,4 @@ + + + + diff --git a/.mcuxpressoide_packages_support/info.properties b/.mcuxpressoide_packages_support/info.properties new file mode 100644 index 0000000..0eacd38 --- /dev/null +++ b/.mcuxpressoide_packages_support/info.properties @@ -0,0 +1,5 @@ +#MCUXpresso IDE +#Wed Sep 14 11:02:46 EEST 2022 +product.name=MCUXpresso IDE v11.5.0 [Build 7232] [2022-01-11] +product.version=11.5.0 +product.build=7232 diff --git a/.mcuxpressoide_packages_support/readme.txt b/.mcuxpressoide_packages_support/readme.txt new file mode 100644 index 0000000..00460b7 --- /dev/null +++ b/.mcuxpressoide_packages_support/readme.txt @@ -0,0 +1,2 @@ +This folder is automatically created and contains the SDK part support for the IDE +*** DO NOT REMOVE OR MODIFY, YOUR CHANGES WILL BE OVERWRITTEN ON SDK REFRESH *** \ No newline at end of file diff --git a/esp-vent-main/.cproject b/esp-vent-main/.cproject new file mode 100644 index 0000000..f6d4886 --- /dev/null +++ b/esp-vent-main/.cproject @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_2="LPC15xx_256K.cfx" property_3="NXP" property_4="LPC1549" property_count="5" version="100300"/> +<infoList vendor="NXP"> +<info chip="LPC1549" connectscript="LPC15RunBootRomConnect.scp" flash_driver="LPC15xx_256K.cfx" match_id="0x0" name="LPC1549" resetscript="LPC15RunBootRomReset.scp" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC1549</name> +<family>LPC15xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" id="Ram0_16" location="0x2000000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram1_16" location="0x2004000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram2_4" location="0x2008000" size="0x1000"/> +</chip> +<processor> +<name gcc_name="cortex-m3">Cortex-M3</name> +<family>Cortex-M</family> +</processor> +</info> +</infoList> +</TargetConfig> + + + LPCXpresso1549 + + \ No newline at end of file diff --git a/esp-vent-main/.gitignore b/esp-vent-main/.gitignore new file mode 100644 index 0000000..3df573f --- /dev/null +++ b/esp-vent-main/.gitignore @@ -0,0 +1 @@ +/Debug/ diff --git a/esp-vent-main/.project b/esp-vent-main/.project new file mode 100644 index 0000000..72a5944 --- /dev/null +++ b/esp-vent-main/.project @@ -0,0 +1,29 @@ + + + esp-vent-main + + + lpc_board_nxp_lpcxpresso_1549 + lpc_chip_15xx + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/esp-vent-main/.settings/language.settings.xml b/esp-vent-main/.settings/language.settings.xml new file mode 100644 index 0000000..5645974 --- /dev/null +++ b/esp-vent-main/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/esp-vent-main/src/cr_cpp_config.cpp b/esp-vent-main/src/cr_cpp_config.cpp new file mode 100644 index 0000000..ba7308e --- /dev/null +++ b/esp-vent-main/src/cr_cpp_config.cpp @@ -0,0 +1,91 @@ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2009-2012 Code Red Technologies Ltd. +// +----+ Copyright 2013, 2019 NXP +// +// Minimal implementations of the new/delete operators and the verbose +// terminate handler for exceptions suitable for embedded use, +// plus optional "null" stubs for malloc/free (only used if symbol +// CPP_NO_HEAP is defined). +// +// +// Version : 120126 +// +// Software License Agreement +// +// The software is owned by Code Red Technologies and/or its suppliers, and is +// protected under applicable copyright laws. All rights are reserved. Any +// use in violation of the foregoing restrictions may subject the user to criminal +// sanctions under applicable laws, as well as to civil liability for the breach +// of the terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT +// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH +// CODE RED TECHNOLOGIES LTD. +// +//***************************************************************************** + +#include + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void *p) +{ + free(p); +} + +void operator delete[](void *p) +{ + free(p); +} + +extern "C" int __aeabi_atexit(void *object, + void (*destructor)(void *), + void *dso_handle) +{ + return 0; +} + +#ifdef CPP_NO_HEAP +extern "C" void *malloc(size_t) { + return (void *)0; +} + +extern "C" void free(void *) { +} +#endif + +#ifndef CPP_USE_CPPLIBRARY_TERMINATE_HANDLER +/****************************************************************** + * __verbose_terminate_handler() + * + * This is the function that is called when an uncaught C++ + * exception is encountered. The default version within the C++ + * library prints the name of the uncaught exception, but to do so + * it must demangle its name - which causes a large amount of code + * to be pulled in. The below minimal implementation can reduce + * code size noticeably. Note that this function should not return. + ******************************************************************/ +namespace __gnu_cxx { +void __verbose_terminate_handler() +{ + while(1); +} +} +#endif diff --git a/esp-vent-main/src/cr_startup_lpc15xx.cpp b/esp-vent-main/src/cr_startup_lpc15xx.cpp new file mode 100644 index 0000000..fe98025 --- /dev/null +++ b/esp-vent-main/src/cr_startup_lpc15xx.cpp @@ -0,0 +1,501 @@ +//***************************************************************************** +// LPC15xx Microcontroller Startup code for use with LPCXpresso IDE +// +// Version : 150706 +//***************************************************************************** +// +// Copyright 2013-2015, 2019, 2020 NXP +// All rights reserved. +// +// NXP Confidential. This software is owned or controlled by NXP and may only be +// used strictly in accordance with the applicable license terms. +// +// By expressly accepting such terms or by downloading, installing, activating +// and/or otherwise using the software, you are agreeing that you have read, and +// that you agree to comply with and are bound by, such license terms. +// +// If you do not agree to be bound by the applicable license terms, then you may not +// retain, install, activate or otherwise use the software. +//***************************************************************************** + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) +// Declaration of external SystemInit function +extern void SystemInit(void); +#endif + +//***************************************************************************** +// +// Forward declaration of the default handlers. These are aliased. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +// +//***************************************************************************** +void ResetISR(void); +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// +// Forward declaration of the specific IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +// +//***************************************************************************** +// Note: The names used for the IRQ Handlers in the LPCXpresso LPC15xx startup +// code did not originally match those used by the LPCOpen LPC15xx packages. +// Now default to using LPCOpen IRQ Handler names. But allow the use of the +// previous names if necessary for legacy code by undefining the below symbol +#define USE_LPCOPEN_IRQHANDLER_NAMES + +#if defined (USE_LPCOPEN_IRQHANDLER_NAMES) +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void FMC_IRQHandler(void) ALIAS(IntDefaultHandler); +void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CAN_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_FIQHandler(void) ALIAS(IntDefaultHandler); +void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0A_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0B_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1A_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1B_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void DAC_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP0_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP1_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP2_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP3_IRQHandler(void) ALIAS(IntDefaultHandler); +void QEI_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_ALARM_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_WAKE_IRQHandler(void) ALIAS(IntDefaultHandler); +#else +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void FLASH_IRQHandler(void) ALIAS(IntDefaultHandler); +void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT4_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT5_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT6_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT7_IRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CAN0_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_FIQHandler(void) ALIAS(IntDefaultHandler); +void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void DAC_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP0_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP2_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP3_IRQHandler(void) ALIAS(IntDefaultHandler); +void QEI_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_ALARM_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_WAKE_IRQHandler(void) ALIAS(IntDefaultHandler); +#endif +//***************************************************************************** +// +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +// +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); +//***************************************************************************** +// +// External declaration for the pointer to the stack top from the Linker Script +// +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +// +// External declaration for LPC MCU vector table checksum from Linker Script +// +//***************************************************************************** +WEAK extern void __valid_user_code_checksum(); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif +//***************************************************************************** +// +// The vector table. +// This relies on the linker script to place at correct location in memory. +// +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +__attribute__ ((used,section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + // Core Level - CM3 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + 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 + __valid_user_code_checksum, // LPC MCU Checksum + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Chip Level - LPC15xx +#if defined (USE_LPCOPEN_IRQHANDLER_NAMES) + WDT_IRQHandler, // 0 - Windowed watchdog timer + BOD_IRQHandler, // 1 - BOD + FMC_IRQHandler, // 2 - Flash controller + EEPROM_IRQHandler, // 3 - EEPROM controller + DMA_IRQHandler, // 4 - DMA + GINT0_IRQHandler, // 5 - GINT0 + GINT1_IRQHandler, // 6 - GINT1 + PIN_INT0_IRQHandler, // 7 - PIO INT0 + PIN_INT1_IRQHandler, // 8 - PIO INT1 + PIN_INT2_IRQHandler, // 9 - PIO INT2 + PIN_INT3_IRQHandler, // 10 - PIO INT3 + PIN_INT4_IRQHandler, // 11 - PIO INT4 + PIN_INT5_IRQHandler, // 12 - PIO INT5 + PIN_INT6_IRQHandler, // 13 - PIO INT6 + PIN_INT7_IRQHandler, // 14 - PIO INT7 + RIT_IRQHandler, // 15 - RIT + SCT0_IRQHandler, // 16 - State configurable timer + SCT1_IRQHandler, // 17 - State configurable timer + SCT2_IRQHandler, // 18 - State configurable timer + SCT3_IRQHandler, // 19 - State configurable timer + MRT_IRQHandler, // 20 - Multi-Rate Timer + UART0_IRQHandler, // 21 - UART0 + UART1_IRQHandler, // 22 - UART1 + UART2_IRQHandler, // 23 - UART2 + I2C0_IRQHandler, // 24 - I2C0 controller + SPI0_IRQHandler, // 25 - SPI0 controller + SPI1_IRQHandler, // 26 - SPI1 controller + CAN_IRQHandler, // 27 - C_CAN0 + USB_IRQHandler, // 28 - USB IRQ + USB_FIQHandler, // 29 - USB FIQ + USBWakeup_IRQHandler, // 30 - USB wake-up + ADC0A_IRQHandler, // 31 - ADC0 sequence A completion + ADC0B_IRQHandler, // 32 - ADC0 sequence B completion + ADC0_THCMP_IRQHandler, // 33 - ADC0 threshold compare + ADC0_OVR_IRQHandler, // 34 - ADC0 overrun + ADC1A_IRQHandler, // 35 - ADC1 sequence A completion + ADC1B_IRQHandler, // 36 - ADC1 sequence B completion + ADC1_THCMP_IRQHandler, // 37 - ADC1 threshold compare + ADC1_OVR_IRQHandler, // 38 - ADC1 overrun + DAC_IRQHandler, // 39 - DAC + ACMP0_IRQHandler, // 40 - Analog Comparator 0 + ACMP1_IRQHandler, // 41 - Analog Comparator 1 + ACMP2_IRQHandler, // 42 - Analog Comparator 2 + ACMP3_IRQHandler, // 43 - Analog Comparator 3 + QEI_IRQHandler, // 44 - QEI + RTC_ALARM_IRQHandler, // 45 - RTC alarm + RTC_WAKE_IRQHandler, // 46 - RTC wake-up +#else + WDT_IRQHandler, // 0 - Windowed watchdog timer + BOD_IRQHandler, // 1 - BOD + FLASH_IRQHandler, // 2 - Flash controller + EEPROM_IRQHandler, // 3 - EEPROM controller + DMA_IRQHandler, // 4 - DMA + GINT0_IRQHandler, // 5 - GINT0 + GINT1_IRQHandler, // 6 - GINT1 + PININT0_IRQHandler, // 7 - PIO INT0 + PININT1_IRQHandler, // 8 - PIO INT1 + PININT2_IRQHandler, // 9 - PIO INT2 + PININT3_IRQHandler, // 10 - PIO INT3 + PININT4_IRQHandler, // 11 - PIO INT4 + PININT5_IRQHandler, // 12 - PIO INT5 + PININT6_IRQHandler, // 13 - PIO INT6 + PININT7_IRQHandler, // 14 - PIO INT7 + RIT_IRQHandler, // 15 - RIT + SCT0_IRQHandler, // 16 - State configurable timer + SCT1_IRQHandler, // 17 - State configurable timer + SCT2_IRQHandler, // 18 - State configurable timer + SCT3_IRQHandler, // 19 - State configurable timer + MRT_IRQHandler, // 20 - Multi-Rate Timer + UART0_IRQHandler, // 21 - UART0 + UART1_IRQHandler, // 22 - UART1 + UART2_IRQHandler, // 23 - UART2 + I2C0_IRQHandler, // 24 - I2C0 controller + SPI0_IRQHandler, // 25 - SPI0 controller + SPI1_IRQHandler, // 26 - SPI1 controller + CAN0_IRQHandler, // 27 - C_CAN0 + USB_IRQHandler, // 28 - USB IRQ + USB_FIQHandler, // 29 - USB FIQ + USBWakeup_IRQHandler, // 30 - USB wake-up + ADC0_SEQA_IRQHandler, // 31 - ADC0 sequence A completion + ADC0_SEQB_IRQHandler, // 32 - ADC0 sequence B completion + ADC0_THCMP_IRQHandler, // 33 - ADC0 threshold compare + ADC0_OVR_IRQHandler, // 34 - ADC0 overrun + ADC1_SEQA_IRQHandler, // 35 - ADC1 sequence A completion + ADC1_SEQB_IRQHandler, // 36 - ADC1 sequence B completion + ADC1_THCMP_IRQHandler, // 37 - ADC1 threshold compare + ADC1_OVR_IRQHandler, // 38 - ADC1 overrun + DAC_IRQHandler, // 39 - DAC + CMP0_IRQHandler, // 40 - Analog Comparator 0 + CMP1_IRQHandler, // 41 - Analog Comparator 1 + CMP2_IRQHandler, // 42 - Analog Comparator 2 + CMP3_IRQHandler, // 43 - Analog Comparator 3 + QEI_IRQHandler, // 44 - QEI + RTC_ALARM_IRQHandler, // 45 - RTC alarm + RTC_WAKE_IRQHandler, // 46 - RTC wake-up +#endif +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void +ResetISR(void) { + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + + // Optionally enable Cortex-M3 SWV trace (off by default at reset) + // Note - your board support must also set up the switch matrix + // so that SWO is output on the appropriate pin for your hardware +#if !defined (DONT_ENABLE_SWVTRACECLK) + // Write 0x00000001 to TRACECLKDIV – Trace divider + volatile unsigned int *TRACECLKDIV = (unsigned int *) 0x400740D8; + *TRACECLKDIV = 1; +#endif + +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) + SystemInit(); +#endif + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main() ; +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void NMI_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void HardFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void MemManage_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void BusFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void UsageFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SVC_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void DebugMon_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void PendSV_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SysTick_Handler(void) +{ while(1) {} +} + +//***************************************************************************** +// +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +// +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void IntDefaultHandler(void) +{ while(1) {} +} + + + diff --git a/esp-vent-main/src/crp.c b/esp-vent-main/src/crp.c new file mode 100644 index 0000000..6e33068 --- /dev/null +++ b/esp-vent-main/src/crp.c @@ -0,0 +1,27 @@ +//***************************************************************************** +// crp.c +// +// Source file to create CRP word expected by LPCXpresso IDE linker +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2013, 2020 +// All rights reserved. +// +// NXP Confidential. This software is owned or controlled by NXP and may only be +// used strictly in accordance with the applicable license terms. +// +// By expressly accepting such terms or by downloading, installing, activating +// and/or otherwise using the software, you are agreeing that you have read, and +// that you agree to comply with and are bound by, such license terms. +// +// If you do not agree to be bound by the applicable license terms, then you may not +// retain, install, activate or otherwise use the software. +//***************************************************************************** + +#if defined (__CODE_RED) +#include +// Variable to store CRP value in. Will be placed automatically +// by the linker when "Enable Code Read Protect" selected. +// See crp.h header for more information +__CRP const unsigned int CRP_WORD = CRP_NO_CRP ; +#endif diff --git a/esp-vent-main/src/esp-vent-main.cpp b/esp-vent-main/src/esp-vent-main.cpp new file mode 100644 index 0000000..b602ec6 --- /dev/null +++ b/esp-vent-main/src/esp-vent-main.cpp @@ -0,0 +1,51 @@ +/* +=============================================================================== + Name : main.c + Author : $(author) + Version : + Copyright : $(copyright) + Description : main definition +=============================================================================== +*/ + +#if defined (__USE_LPCOPEN) +#if defined(NO_BOARD_LIB) +#include "chip.h" +#else +#include "board.h" +#endif +#endif + +#include + +// TODO: insert other include files here + +// TODO: insert other definitions and declarations here + +int main(void) { + +#if defined (__USE_LPCOPEN) + // Read clock settings and update SystemCoreClock variable + SystemCoreClockUpdate(); +#if !defined(NO_BOARD_LIB) + // Set up and initialize all required blocks and + // functions related to the board hardware + Board_Init(); + // Set the LED to the state of "On" + Board_LED_Set(0, true); +#endif +#endif + + // TODO: insert code here + + // Force the counter to be placed into memory + volatile static int i = 0 ; + // Enter an infinite loop, just incrementing a counter + while(1) { + i++ ; + // "Dummy" NOP to allow source level single + // stepping of tight while() loop + __asm volatile ("nop"); + } + return 0 ; +} diff --git a/esp-vent-main/src/sysinit.c b/esp-vent-main/src/sysinit.c new file mode 100644 index 0000000..7666b07 --- /dev/null +++ b/esp-vent-main/src/sysinit.c @@ -0,0 +1,57 @@ +/* + * @brief Common SystemInit function for LPC15xx chips + * + * @note + * Copyright 2013-2014, 2019, 2020 NXP + * All rights reserved. + * + * @par + * NXP Confidential. This software is owned or controlled by NXP and may only be + * used strictly in accordance with the applicable license terms. + * + * By expressly accepting such terms or by downloading, installing, activating + * and/or otherwise using the software, you are agreeing that you have read, and + * that you agree to comply with and are bound by, such license terms. + * + * If you do not agree to be bound by the applicable license terms, then you may not + * retain, install, activate or otherwise use the software. + */ + + #if defined(NO_BOARD_LIB) + #include "chip.h" + #else + #include "board.h" + #endif + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +#if defined(NO_BOARD_LIB) +const uint32_t OscRateIn = 12000000; +const uint32_t RTCOscRateIn = 32768; +#endif + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set up and initialize hardware prior to call to main */ +void SystemInit(void) +{ +#if defined(NO_BOARD_LIB) + /* Chip specific SystemInit */ + Chip_SystemInit(); +#else + /* Board specific SystemInit */ + Board_SystemInit(); +#endif +} diff --git a/lpc_board_nxp_lpcxpresso_1549/.cproject b/lpc_board_nxp_lpcxpresso_1549/.cproject new file mode 100644 index 0000000..4b75152 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/.cproject @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_0="" property_2="LPC15xx_256K.cfx" property_3="NXP" property_4="LPC1549" property_count="5" version="70200"/> +<infoList vendor="NXP"> +<info chip="LPC1549" connectscript="LPC15RunBootRomConnect.scp" flash_driver="LPC15xx_256K.cfx" match_id="0x0" name="LPC1549" resetscript="LPC15RunBootRomReset.scp" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC1549</name> +<family>LPC15xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" id="Ram0_16" location="0x2000000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram1_16" location="0x2004000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram2_4" location="0x2008000" size="0x1000"/> +<peripheralInstance derived_from="V7M_MPU" determined="infoFile" id="MPU" location="0xe000ed90"/> +<peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/> +<peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/> +<peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/> +<peripheralInstance derived_from="GPIO-PORT" determined="infoFile" id="GPIO-PORT" location="0x1c000000"/> +<peripheralInstance derived_from="DMA" determined="infoFile" id="DMA" location="0x1c004000"/> +<peripheralInstance derived_from="USB" determined="infoFile" id="USB" location="0x1c00c000"/> +<peripheralInstance derived_from="CRC" determined="infoFile" id="CRC" location="0x1c010000"/> +<peripheralInstance derived_from="SCT0" determined="infoFile" id="SCT0" location="0x1c018000"/> +<peripheralInstance derived_from="SCT1" determined="infoFile" id="SCT1" location="0x1c01c000"/> +<peripheralInstance derived_from="SCT2" determined="infoFile" id="SCT2" location="0x1c020000"/> +<peripheralInstance derived_from="SCT3" determined="infoFile" id="SCT3" location="0x1c024000"/> +<peripheralInstance derived_from="ADC0" determined="infoFile" id="ADC0" location="0x40000000"/> +<peripheralInstance derived_from="DAC" determined="infoFile" id="DAC" location="0x40004000"/> +<peripheralInstance derived_from="ACMP" determined="infoFile" id="ACMP" location="0x40008000"/> +<peripheralInstance derived_from="INMUX" determined="infoFile" id="INMUX" location="0x40014000"/> +<peripheralInstance derived_from="RTC" determined="infoFile" id="RTC" location="0x40028000"/> +<peripheralInstance derived_from="WWDT" determined="infoFile" id="WWDT" location="0x4002c000"/> +<peripheralInstance derived_from="SWM" determined="infoFile" id="SWM" location="0x40038000"/> +<peripheralInstance derived_from="PMU" determined="infoFile" id="PMU" location="0x4003c000"/> +<peripheralInstance derived_from="USART0" determined="infoFile" id="USART0" location="0x40040000"/> +<peripheralInstance derived_from="USART1" determined="infoFile" id="USART1" location="0x40044000"/> +<peripheralInstance derived_from="SPI0" determined="infoFile" id="SPI0" location="0x40048000"/> +<peripheralInstance derived_from="SPI1" determined="infoFile" id="SPI1" location="0x4004c000"/> +<peripheralInstance derived_from="I2C0" determined="infoFile" id="I2C0" location="0x40050000"/> +<peripheralInstance derived_from="QEI" determined="infoFile" id="QEI" location="0x40058000"/> +<peripheralInstance derived_from="SYSCON" determined="infoFile" id="SYSCON" location="0x40074000"/> +<peripheralInstance derived_from="ADC1" determined="infoFile" id="ADC1" location="0x40080000"/> +<peripheralInstance derived_from="MRT" determined="infoFile" id="MRT" location="0x400a0000"/> +<peripheralInstance derived_from="PINT" determined="infoFile" id="PINT" location="0x400a4000"/> +<peripheralInstance derived_from="GINT0" determined="infoFile" id="GINT0" location="0x400a8000"/> +<peripheralInstance derived_from="GINT1" determined="infoFile" id="GINT1" location="0x400ac000"/> +<peripheralInstance derived_from="RIT" determined="infoFile" id="RIT" location="0x400b4000"/> +<peripheralInstance derived_from="SCTIPU" determined="infoFile" id="SCTIPU" location="0x400b8000"/> +<peripheralInstance derived_from="FLASHCTRL" determined="infoFile" id="FLASHCTRL" location="0x400bc000"/> +<peripheralInstance derived_from="USART2" determined="infoFile" id="USART2" location="0x400c0000"/> +<peripheralInstance derived_from="C-CAN0" determined="infoFile" id="C-CAN0" location="0x400f0000"/> +<peripheralInstance derived_from="IOCON" determined="infoFile" id="IOCON" location="0x400f8000"/> +</chip> +<processor> +<name gcc_name="cortex-m3">Cortex-M3</name> +<family>Cortex-M</family> +</processor> +<link href="LPC15xx_peripheral.xme" show="embed" type="simple"/> +</info> +</infoList> +</TargetConfig> + + diff --git a/lpc_board_nxp_lpcxpresso_1549/.gitignore b/lpc_board_nxp_lpcxpresso_1549/.gitignore new file mode 100644 index 0000000..3df573f --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/.gitignore @@ -0,0 +1 @@ +/Debug/ diff --git a/lpc_board_nxp_lpcxpresso_1549/.project b/lpc_board_nxp_lpcxpresso_1549/.project new file mode 100644 index 0000000..d4f0d44 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/.project @@ -0,0 +1,26 @@ + + + lpc_board_nxp_lpcxpresso_1549 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/lpc_board_nxp_lpcxpresso_1549/.settings/language.settings.xml b/lpc_board_nxp_lpcxpresso_1549/.settings/language.settings.xml new file mode 100644 index 0000000..48af2ca --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lpc_board_nxp_lpcxpresso_1549/inc/board.h b/lpc_board_nxp_lpcxpresso_1549/inc/board.h new file mode 100644 index 0000000..c7cd7a7 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/inc/board.h @@ -0,0 +1,111 @@ +/* + * @brief LPCXPresso LPC1549 board file + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __BOARD_H_ +#define __BOARD_H_ + +#include "chip.h" +/* board_api.h is included at the bottom of this file after DEBUG setup */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BOARD_NXP_LPCXPRESSO_1549 LPCXPresso LPC1549 board support software API functions + * @ingroup LPCOPEN_15XX_NXP_LPCXPRESSO_1549 + * The board support software API functions provide some simple abstracted + * functions used across multiple LPCOpen board examples. See @ref BOARD_COMMON_API + * for the functions defined by this board support layer.
+ * @{ + */ + +/** @defgroup BOARD_NXP_LPCXPRESSO_1549_OPTIONS BOARD: LPCXPresso LPC1549 board build options + * This board has options that configure its operation at build-time.
+ * @{ + */ + +/** Define DEBUG_ENABLE to enable IO via the DEBUGSTR, DEBUGOUT, and + DEBUGIN macros. If not defined, DEBUG* functions will be optimized + out of the code at build time. + */ +#define DEBUG_ENABLE + +/** Define DEBUG_SEMIHOSTING along with DEBUG_ENABLE to enable IO support + via semihosting. You may need to use a C library that supports + semihosting with this option. + */ +// #define DEBUG_SEMIHOSTING + +/** Board UART used for debug output and input using the DEBUG* macros. This + is also the port used for Board_UARTPutChar, Board_UARTGetChar, and + Board_UARTPutSTR functions. + */ +#define DEBUG_UART LPC_USART0 + +/** + * @} + */ + +/* Board name */ +#define BOARD_NXP_LPCXPRESSO_1549 + +/** + * Joystick defines + */ +#define JOY_UP 0x01 +#define JOY_DOWN 0x02 +#define JOY_LEFT 0x04 +#define JOY_RIGHT 0x08 +#define JOY_PRESS 0x10 + +/** + * @brief Initialize Joystick + * @return Nothing + */ +void Board_Joystick_Init(void); + +/** + * @brief Get Joystick status + * @return status of Joystick + */ +uint8_t Joystick_GetStatus(void); + +/** + * @} + */ + +#include "board_api.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __BOARD_H_ */ diff --git a/lpc_board_nxp_lpcxpresso_1549/inc/board_api.h b/lpc_board_nxp_lpcxpresso_1549/inc/board_api.h new file mode 100644 index 0000000..b08ee18 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/inc/board_api.h @@ -0,0 +1,196 @@ +/* + * @brief Common board API functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __BOARD_API_H_ +#define __BOARD_API_H_ + +#include "lpc_types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BOARD_COMMON_API BOARD: Common board functions + * @ingroup BOARD_Common + * This file contains common board definitions that are shared across + * boards and devices. All of these functions do not need to be + * implemented for a specific board, but if they are implemented, they + * should use this API standard. + * @{ + */ + +/** + * @brief Setup and initialize hardware prior to call to main() + * @return None + * @note Board_SystemInit() is called prior to the application and sets up system + * clocking, memory, and any resources needed prior to the application + * starting. + */ +void Board_SystemInit(void); + +/** + * @brief Setup pin multiplexer per board schematics + * @return None + * @note Board_SetupMuxing() should be called from SystemInit() prior to application + * main() is called. So that the PINs are set in proper state. + */ +void Board_SetupMuxing(void); + +/** + * @brief Setup system clocking + * @return None + * @note This sets up board clocking. + */ +void Board_SetupClocking(void); + +/** + * @brief Setup external system memory + * @return None + * @note This function is typically called after pin mux setup and clock setup and + * sets up any external memory needed by the system (DRAM, SRAM, etc.). Not all + * boards need this function. + */ +void Board_SetupExtMemory(void); + +/** + * @brief Set up and initialize all required blocks and functions related to the board hardware. + * @return None + */ +void Board_Init(void); + +/** + * @brief Initializes board UART for output, required for printf redirection + * @return None + */ +void Board_Debug_Init(void); + +/** + * @brief Sends a single character on the UART, required for printf redirection + * @param ch : character to send + * @return None + */ +void Board_UARTPutChar(char ch); + +/** + * @brief Classic implementation of itoa -- integer to ASCII + * @param value : value to convert + * @param result : result string + * @param base : output radix + * @return result string or NULL + */ +char *Board_itoa(int value, char *result, int base); + +/** + * @brief Get a single character from the UART, required for scanf input + * @return EOF if not character was received, or character value + */ +int Board_UARTGetChar(void); + +/** + * @brief Prints a string to the UART + * @param str : Terminated string to output + * @return None + */ +void Board_UARTPutSTR(const char *str); + +/** + * @brief Sets the state of a board LED to on or off + * @param LEDNumber : LED number to set state for + * @param State : true for on, false for off + * @return None + */ +void Board_LED_Set(uint8_t LEDNumber, bool State); + +/** + * @brief Returns the current state of a board LED + * @param LEDNumber : LED number to set state for + * @return true if the LED is on, otherwise false + */ +bool Board_LED_Test(uint8_t LEDNumber); + +/** + * @brief Toggles the current state of a board LED + * @param LEDNumber : LED number to change state for + * @return None + */ +void Board_LED_Toggle(uint8_t LEDNumber); + +/** + * @brief Turn on Board LCD Backlight + * @param Intensity : Backlight intensity (0 = off, >=1 = on) + * @return None + * @note On boards where a GPIO is used to control backlight on/off state, a '0' or '1' + * value will turn off or on the backlight. On some boards, a non-0 value will + * control backlight intensity via a PWN. For PWM systems, the intensity value + * is a percentage value between 0 and 100%. + */ +void Board_SetLCDBacklight(uint8_t Intensity); + +/** + * @brief Function prototype for a MS delay function. Board layers or example code may + * define this function as needed. + */ +typedef void (*p_msDelay_func_t)(uint32_t); + +/* The DEBUG* functions are selected based on system configuration. + Code that uses the DEBUG* functions will have their I/O routed to + the UART, semihosting, or nowhere. */ +#if defined(DEBUG_ENABLE) +#if defined(DEBUG_SEMIHOSTING) +#define DEBUGINIT() +#define DEBUGOUT(...) printf(__VA_ARGS__) +#define DEBUGSTR(str) printf(str) +#define DEBUGIN() (int) EOF + +#else +#define DEBUGINIT() Board_Debug_Init() +#define DEBUGOUT(...) printf(__VA_ARGS__) +#define DEBUGSTR(str) Board_UARTPutSTR(str) +#define DEBUGIN() Board_UARTGetChar() +#endif /* defined(DEBUG_SEMIHOSTING) */ + +#else +#define DEBUGINIT() +#define DEBUGOUT(...) +#define DEBUGSTR(str) +#define DEBUGIN() (int) EOF +#endif /* defined(DEBUG_ENABLE) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __BOARD_API_H_ */ diff --git a/lpc_board_nxp_lpcxpresso_1549/src/board.c b/lpc_board_nxp_lpcxpresso_1549/src/board.c new file mode 100644 index 0000000..09af311 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/src/board.c @@ -0,0 +1,198 @@ +/* + * @brief LPCXPresso LPC1549 board file + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "board.h" +#include "retarget.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/* System oscillator rate and RTC oscillator rate */ +const uint32_t OscRateIn = 12000000; +const uint32_t RTCOscRateIn = 32768; + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Sends a character on the UART */ +void Board_UARTPutChar(char ch) +{ +#if defined(DEBUG_UART) + Chip_UART_SendBlocking(DEBUG_UART, &ch, 1); +#endif +} + +/* Gets a character from the UART, returns EOF if no character is ready */ +int Board_UARTGetChar(void) +{ +#if defined(DEBUG_UART) + uint8_t data; + + if (Chip_UART_Read(DEBUG_UART, &data, 1) == 1) { + return (int) data; + } +#endif + return EOF; +} + +/* Outputs a string on the debug UART */ +void Board_UARTPutSTR(const char *str) +{ +#if defined(DEBUG_UART) + while (*str != '\0') { + Board_UARTPutChar(*str++); + } +#endif +} + +/* Initialize debug output via UART for board */ +void Board_Debug_Init(void) +{ +#if defined(DEBUG_UART) + /* Disables pullups/pulldowns and enable digitial mode */ + Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 13, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + /* UART signal muxing via SWM */ + Chip_SWM_MovablePortPinAssign(SWM_UART0_RXD_I, 0, 13); + Chip_SWM_MovablePortPinAssign(SWM_UART0_TXD_O, 0, 18); + + /* Use main clock rate as base for UART baud rate divider */ + Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false); + + /* Setup UART */ + Chip_UART_Init(DEBUG_UART); + Chip_UART_ConfigData(DEBUG_UART, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1); + Chip_UART_SetBaud(DEBUG_UART, 115200); + Chip_UART_Enable(DEBUG_UART); + Chip_UART_TXEnable(DEBUG_UART); +#endif +} + +#define MAXLEDS 3 +static const uint8_t ledpins[MAXLEDS] = {25, 3, 1}; +static const uint8_t ledports[MAXLEDS] = {0, 0, 1}; + +/* Initializes board LED(s) */ +static void Board_LED_Init(void) +{ + int idx; + + for (idx = 0; idx < MAXLEDS; idx++) { + /* Set the GPIO as output with initial state off (high) */ + Chip_GPIO_SetPinDIROutput(LPC_GPIO, ledports[idx], ledpins[idx]); + Chip_GPIO_SetPinState(LPC_GPIO, ledports[idx], ledpins[idx], true); + } +} + +/* Sets the state of a board LED to on or off */ +void Board_LED_Set(uint8_t LEDNumber, bool On) +{ + if (LEDNumber < MAXLEDS) { + /* Toggle state, low is on, high is off */ + Chip_GPIO_SetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber], !On); + } +} + +/* Returns the current state of a board LED */ +bool Board_LED_Test(uint8_t LEDNumber) +{ + bool state = false; + + if (LEDNumber < MAXLEDS) { + state = !Chip_GPIO_GetPinState(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]); + } + + return state; +} + +/* Toggles the current state of a board LED */ +void Board_LED_Toggle(uint8_t LEDNumber) +{ + Chip_GPIO_SetPinToggle(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]); +} + +/* Set up and initialize all required blocks and functions related to the + board hardware */ +void Board_Init(void) +{ + /* Sets up DEBUG UART */ + DEBUGINIT(); + + /* Initialize GPIO */ + Chip_GPIO_Init(LPC_GPIO); + + /* Initialize LEDs */ + Board_LED_Init(); +} + +/* Ordered up, down, left, right, press */ +#define NUM_BUTTONS 5 +static const uint8_t portButton[NUM_BUTTONS] = {1, 1, 1, 1, 1}; +static const uint8_t pinButton[NUM_BUTTONS] = {4, 6, 8, 7, 5}; +static const uint8_t stateButton[NUM_BUTTONS] = {JOY_UP, JOY_DOWN, JOY_LEFT, + JOY_RIGHT, JOY_PRESS}; + +/* Initialize Joystick */ +void Board_Joystick_Init(void) +{ + int i; + + /* IOCON states already selected in SystemInit(), GPIO setup only. Pullups + are external, so IOCON with no states */ + for (i = 0; i < NUM_BUTTONS; i++) { + Chip_GPIO_SetPinDIRInput(LPC_GPIO, portButton[i], pinButton[i]); + } +} + +/* Get Joystick status */ +uint8_t Joystick_GetStatus(void) +{ + uint8_t i, ret = 0; + + for (i = 0; i < NUM_BUTTONS; i++) { + if ((Chip_GPIO_GetPinState(LPC_GPIO, portButton[i], pinButton[i])) == 0x00) { + ret |= stateButton[i]; + } + } + + return ret; +} diff --git a/lpc_board_nxp_lpcxpresso_1549/src/board_sysinit.c b/lpc_board_nxp_lpcxpresso_1549/src/board_sysinit.c new file mode 100644 index 0000000..869f393 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/src/board_sysinit.c @@ -0,0 +1,183 @@ +/* + * @brief LPCXPresso LPC1549 Sysinit file + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + + #include "board.h" + #include "string.h" + +/* The System initialization code is called prior to the application and + initializes the board for run-time operation. Board initialization + includes clock setup and default pin muxing configuration. */ + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* IOCON setup table, only items that need changing from their default pin + state are in this table. */ +STATIC const PINMUX_GRP_T ioconSetup[] = { + /* LEDs */ + {0, 25, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_25-BREAK_CTRL-RED (low enable) */ + {0, 3, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_3-SCT1_OUT4-GRN */ + {1, 1, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_1-BREAK_STS1-BLUE */ + + /* QEI, motor controler, I2C, CAN */ + {0, 2, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_2-QEI-SCT0_IN */ + {0, 30, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_30-QEI-SCT0_IN */ + {0, 17, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_17-QEI-SCT0_IN */ + {0, 25, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_25-BREAK_CTRL-RED */ + {1, 1, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_1-BREAK_STS1-BLUE */ + {0, 23, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_23-I2C_SDA */ + {0, 22, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_22-I2C_SCL */ + {0, 11, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_11-CAN_RD */ + {0, 31, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_31-CAN_TD */ + + /* ADC */ + {1, 3, (IOCON_MODE_INACT)}, /* PIO1_3-ADC1_5 */ + {0, 4, (IOCON_MODE_INACT)}, /* PIO0_4-ADC0_4 */ + {0, 5, (IOCON_MODE_INACT)}, /* PIO0_5-ADC0_3 */ + {0, 7, (IOCON_MODE_INACT)}, /* PIO0_7-ADC0_1 */ + {0, 8, (IOCON_MODE_INACT)}, /* PIO0_8-ADC0_0 */ + {0, 9, (IOCON_MODE_INACT)}, /* PIO0_9-ADC1_1 */ + {0, 10, (IOCON_MODE_INACT)}, /* PIO0_10-ADC1_2 */ + + /* Joystick */ + {1, 4, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_4-JOY_U */ + {1, 5, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_5-JOY_C */ + {1, 6, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_6-JOY_D */ + {1, 7, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_7-JOY_R */ + {1, 8, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO1_8-JOY_L */ + + /* UART */ + {0, 13, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_13-ISP_RX */ + {0, 18, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, /* PIO0_18-ISP_TX */ + {0, 11, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, + {0, 31, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, + + /* USB related */ + {1, 11, (IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN)}, /* PIO1_11-ISP_1 (VBUS) */ +}; + +/* SWIM pin assignment definitions for pin assignment/muxing */ +typedef struct { + uint16_t assignedpin : 9; /* Function and mode */ + uint16_t port : 2; /* Pin port */ + uint16_t pin : 5; /* Pin number */ +} SWM_GRP_T; + +/* Pin muxing table, only items that need changing from their default pin + state are in this table. */ +STATIC const SWM_GRP_T swmSetup[] = { + /* USB related */ + {(uint16_t) SWM_USB_VBUS_I, 1, 11}, /* PIO1_11-ISP_1-AIN_CTRL */ + + /* UART */ + {(uint16_t) SWM_UART0_RXD_I, 0, 13}, /* PIO0_13-ISP_RX */ + {(uint16_t) SWM_UART0_TXD_O, 0, 18}, /* PIO0_18-ISP_TX */ +}; + +/* Setup fixed pin functions (GPIOs are fixed) */ +/* No fixed pins except GPIOs */ +#define PINENABLE0_VAL 0xFFFFFFFF + +/* No fixed pins except GPIOs */ +#define PINENABLE1_VAL 0x00FFFFFF + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Sets up system pin muxing */ +void Board_SetupMuxing(void) +{ + int i; + + /* Enable SWM and IOCON clocks */ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM); + Chip_SYSCTL_PeriphReset(RESET_IOCON); + + /* IOCON setup */ + Chip_IOCON_SetPinMuxing(LPC_IOCON, ioconSetup, sizeof(ioconSetup) / sizeof(PINMUX_GRP_T)); + + /* SWM assignable pin setup */ + for (i = 0; i < (sizeof(swmSetup) / sizeof(SWM_GRP_T)); i++) { + Chip_SWM_MovablePortPinAssign((CHIP_SWM_PIN_MOVABLE_T) swmSetup[i].assignedpin, + swmSetup[i].port, swmSetup[i].pin); + } + + /* SWM fixed pin setup */ + // LPC_SWM->PINENABLE[0] = PINENABLE0_VAL; + // LPC_SWM->PINENABLE[1] = PINENABLE1_VAL; + + /* Note SWM and IOCON clocks are left on */ +} + +/* Set up and initialize clocking prior to call to main */ +void Board_SetupClocking(void) +{ + Chip_SetupXtalClocking(); + + /* Set USB PLL input to main oscillator */ + Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_MAINOSC); + /* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz + MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz + FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */ + Chip_Clock_SetupUSBPLL(3, 1); + + /* Powerup USB PLL */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD); + + /* Wait for PLL to lock */ + while (!Chip_Clock_IsUSBPLLLocked()) {} + + /* Set default system tick divder to 1 */ + Chip_Clock_SetSysTickClockDiv(1); +} + +/* Set up and initialize hardware prior to call to main */ +void Board_SystemInit(void) +{ + /* Setup system clocking and muxing */ + Board_SetupMuxing(); + Board_SetupClocking(); + + /* Set SYSTICKDIV to 1 so CMSIS Systick functions work */ + LPC_SYSCTL->SYSTICKCLKDIV = 1; +} diff --git a/lpc_board_nxp_lpcxpresso_1549/src/retarget.h b/lpc_board_nxp_lpcxpresso_1549/src/retarget.h new file mode 100644 index 0000000..852d2f1 --- /dev/null +++ b/lpc_board_nxp_lpcxpresso_1549/src/retarget.h @@ -0,0 +1,275 @@ +/* + * @brief IO redirection support + * + * This file adds re-direction support to the library for various + * projects. It can be configured in one of 3 ways - no redirection, + * redirection via a UART, or redirection via semihosting. If DEBUG + * is not defined, all printf statements will do nothing with the + * output being throw away. If DEBUG is defined, then the choice of + * output is selected by the DEBUG_SEMIHOSTING define. If the + * DEBUG_SEMIHOSTING is not defined, then output is redirected via + * the UART. If DEBUG_SEMIHOSTING is defined, then output will be + * attempted to be redirected via semihosting. If the UART method + * is used, then the Board_UARTPutChar and Board_UARTGetChar + * functions must be defined to be used by this driver and the UART + * must already be initialized to the correct settings. + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "board.h" + +/* Keil (Realview) support */ +#if defined(__CC_ARM) + +#include +#include + +#if defined(DEBUG_ENABLE) +#if defined(DEBUG_SEMIHOSTING) +#define ITM_Port8(n) (*((volatile unsigned char *) (0xE0000000 + 4 * n))) +#define ITM_Port16(n) (*((volatile unsigned short *) (0xE0000000 + 4 * n))) +#define ITM_Port32(n) (*((volatile unsigned long *) (0xE0000000 + 4 * n))) + +#define DEMCR (*((volatile unsigned long *) (0xE000EDFC))) +#define TRCENA 0x01000000 + +/* Write to SWO */ +void _ttywrch(int ch) +{ + if (DEMCR & TRCENA) { + while (ITM_Port32(0) == 0) {} + ITM_Port8(0) = ch; + } +} + +#else +static INLINE void BoardOutChar(char ch) +{ + Board_UARTPutChar(ch); +} + +#endif /* defined(DEBUG_SEMIHOSTING) */ +#endif /* defined(DEBUG_ENABLE) */ + +struct __FILE { + int handle; +}; + +FILE __stdout; +FILE __stdin; +FILE __stderr; + +void *_sys_open(const char *name, int openmode) +{ + return 0; +} + +int fputc(int c, FILE *f) +{ +#if defined(DEBUG_ENABLE) +#if defined(DEBUG_SEMIHOSTING) + _ttywrch(c); +#else + BoardOutChar((char) c); +#endif +#endif + return 0; +} + +int fgetc(FILE *f) +{ +#if defined(DEBUG_ENABLE) && !defined(DEBUG_SEMIHOSTING) + return Board_UARTGetChar(); +#else + return 0; +#endif +} + +int ferror(FILE *f) +{ + return EOF; +} + +void _sys_exit(int return_code) +{ +label: + __WFI(); + goto label; /* endless loop */ +} + +#endif /* defined (__CC_ARM) */ + +/* IAR support */ +#if defined(__ICCARM__) +/******************* + * + * Copyright 1998-2003 IAR Systems. All rights reserved. + * + * $Revision: 30870 $ + * + * This is a template implementation of the "__write" function used by + * the standard library. Replace it with a system-specific + * implementation. + * + * The "__write" function should output "size" number of bytes from + * "buffer" in some application-specific way. It should return the + * number of characters written, or _LLIO_ERROR on failure. + * + * If "buffer" is zero then __write should perform flushing of + * internal buffers, if any. In this case "handle" can be -1 to + * indicate that all handles should be flushed. + * + * The template implementation below assumes that the application + * provides the function "MyLowLevelPutchar". It should return the + * character written, or -1 on failure. + * + ********************/ + +#include + +#if defined(DEBUG_ENABLE) && !defined(DEBUG_SEMIHOSTING) + +_STD_BEGIN + +#pragma module_name = "?__write" + +/* + If the __write implementation uses internal buffering, uncomment + the following line to ensure that we are called with "buffer" as 0 + (i.e. flush) when the application terminates. */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ +#if defined(DEBUG_ENABLE) + size_t nChars = 0; + + if (buffer == 0) { + /* + This means that we should flush internal buffers. Since we + don't we just return. (Remember, "handle" == -1 means that all + handles should be flushed.) + */ + return 0; + } + + /* This template only writes to "standard out" and "standard err", + for all other file handles it returns failure. */ + if (( handle != _LLIO_STDOUT) && ( handle != _LLIO_STDERR) ) { + return _LLIO_ERROR; + } + + for ( /* Empty */; size != 0; --size) { + Board_UARTPutChar(*buffer++); + ++nChars; + } + + return nChars; +#else + return size; +#endif /* defined(DEBUG_ENABLE) */ +} + +_STD_END +#endif + +#endif /* defined (__ICCARM__) */ + +#if defined( __GNUC__ ) +/* Include stdio.h to pull in __REDLIB_INTERFACE_VERSION__ */ +#include + +#if defined(__NEWLIB__) + #define WRITEFUNC _write + #define READFUNC _read +#else +#if (__REDLIB_INTERFACE_VERSION__ >= 20000) +/* We are using new Redlib_v2 semihosting interface */ + #define WRITEFUNC __sys_write + #define READFUNC __sys_readc +#else +/* We are using original Redlib semihosting interface */ + #define WRITEFUNC __write + #define READFUNC __readc +#endif +#endif /* __NEWLIB__ */ + +#if defined(DEBUG_ENABLE) +#if defined(DEBUG_SEMIHOSTING) +/* Do nothing, semihosting is enabled by default in LPCXpresso */ +#endif /* defined(DEBUG_SEMIHOSTING) */ +#endif /* defined(DEBUG_ENABLE) */ + +#if !defined(DEBUG_SEMIHOSTING) +int WRITEFUNC(int iFileHandle, char *pcBuffer, int iLength) +{ +#if defined(DEBUG_ENABLE) + unsigned int i; + for (i = 0; i < iLength; i++) { + Board_UARTPutChar(pcBuffer[i]); + } +#endif + + return iLength; +} + +#if !defined(__NEWLIB__) +/* Called by bottom level of scanf routine within RedLib C library to read + a character. With the default semihosting stub, this would read the character + from the debugger console window (which acts as stdin). But this version reads + the character from the LPC1768/RDB1768 UART. */ +int READFUNC(void) +{ +#if defined(DEBUG_ENABLE) + int c = Board_UARTGetChar(); + return c; + +#else + return (int) -1; +#endif +} +#else +/* + * **WARNING**: THIS FUNCTION IS NON-BLOCKING + * Not just STDIN all inputs handled via UART + * Read function for newlib is added as a non-blocking function + * the application should check for the size to identify the number + * of bytes received */ +int READFUNC(int iFileHandle, char *pcBuffer, int iLength) +{ + int idx; + for (idx = 0; idx < iLength; idx++) { + int c = Board_UARTGetChar(); + if (c == EOF) break; + pcBuffer[idx] = c; + } + return idx; +} +#endif + +#endif /* !defined(DEBUG_SEMIHOSTING) */ +#endif /* defined ( __GNUC__ ) */ diff --git a/lpc_chip_15xx/.cproject b/lpc_chip_15xx/.cproject new file mode 100644 index 0000000..f86ad24 --- /dev/null +++ b/lpc_chip_15xx/.cproject @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_0="" property_2="LPC15xx_256K.cfx" property_3="NXP" property_4="LPC1549" property_count="5" version="70200"/> +<infoList vendor="NXP"> +<info chip="LPC1549" connectscript="LPC15RunBootRomConnect.scp" flash_driver="LPC15xx_256K.cfx" match_id="0x0" name="LPC1549" resetscript="LPC15RunBootRomReset.scp" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC1549</name> +<family>LPC15xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" id="Ram0_16" location="0x2000000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram1_16" location="0x2004000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram2_4" location="0x2008000" size="0x1000"/> +<peripheralInstance derived_from="V7M_MPU" determined="infoFile" id="MPU" location="0xe000ed90"/> +<peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/> +<peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/> +<peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/> +<peripheralInstance derived_from="GPIO-PORT" determined="infoFile" id="GPIO-PORT" location="0x1c000000"/> +<peripheralInstance derived_from="DMA" determined="infoFile" id="DMA" location="0x1c004000"/> +<peripheralInstance derived_from="USB" determined="infoFile" id="USB" location="0x1c00c000"/> +<peripheralInstance derived_from="CRC" determined="infoFile" id="CRC" location="0x1c010000"/> +<peripheralInstance derived_from="SCT0" determined="infoFile" id="SCT0" location="0x1c018000"/> +<peripheralInstance derived_from="SCT1" determined="infoFile" id="SCT1" location="0x1c01c000"/> +<peripheralInstance derived_from="SCT2" determined="infoFile" id="SCT2" location="0x1c020000"/> +<peripheralInstance derived_from="SCT3" determined="infoFile" id="SCT3" location="0x1c024000"/> +<peripheralInstance derived_from="ADC0" determined="infoFile" id="ADC0" location="0x40000000"/> +<peripheralInstance derived_from="DAC" determined="infoFile" id="DAC" location="0x40004000"/> +<peripheralInstance derived_from="ACMP" determined="infoFile" id="ACMP" location="0x40008000"/> +<peripheralInstance derived_from="INMUX" determined="infoFile" id="INMUX" location="0x40014000"/> +<peripheralInstance derived_from="RTC" determined="infoFile" id="RTC" location="0x40028000"/> +<peripheralInstance derived_from="WWDT" determined="infoFile" id="WWDT" location="0x4002c000"/> +<peripheralInstance derived_from="SWM" determined="infoFile" id="SWM" location="0x40038000"/> +<peripheralInstance derived_from="PMU" determined="infoFile" id="PMU" location="0x4003c000"/> +<peripheralInstance derived_from="USART0" determined="infoFile" id="USART0" location="0x40040000"/> +<peripheralInstance derived_from="USART1" determined="infoFile" id="USART1" location="0x40044000"/> +<peripheralInstance derived_from="SPI0" determined="infoFile" id="SPI0" location="0x40048000"/> +<peripheralInstance derived_from="SPI1" determined="infoFile" id="SPI1" location="0x4004c000"/> +<peripheralInstance derived_from="I2C0" determined="infoFile" id="I2C0" location="0x40050000"/> +<peripheralInstance derived_from="QEI" determined="infoFile" id="QEI" location="0x40058000"/> +<peripheralInstance derived_from="SYSCON" determined="infoFile" id="SYSCON" location="0x40074000"/> +<peripheralInstance derived_from="ADC1" determined="infoFile" id="ADC1" location="0x40080000"/> +<peripheralInstance derived_from="MRT" determined="infoFile" id="MRT" location="0x400a0000"/> +<peripheralInstance derived_from="PINT" determined="infoFile" id="PINT" location="0x400a4000"/> +<peripheralInstance derived_from="GINT0" determined="infoFile" id="GINT0" location="0x400a8000"/> +<peripheralInstance derived_from="GINT1" determined="infoFile" id="GINT1" location="0x400ac000"/> +<peripheralInstance derived_from="RIT" determined="infoFile" id="RIT" location="0x400b4000"/> +<peripheralInstance derived_from="SCTIPU" determined="infoFile" id="SCTIPU" location="0x400b8000"/> +<peripheralInstance derived_from="FLASHCTRL" determined="infoFile" id="FLASHCTRL" location="0x400bc000"/> +<peripheralInstance derived_from="USART2" determined="infoFile" id="USART2" location="0x400c0000"/> +<peripheralInstance derived_from="C-CAN0" determined="infoFile" id="C-CAN0" location="0x400f0000"/> +<peripheralInstance derived_from="IOCON" determined="infoFile" id="IOCON" location="0x400f8000"/> +</chip> +<processor> +<name gcc_name="cortex-m3">Cortex-M3</name> +<family>Cortex-M</family> +</processor> +<link href="LPC15xx_peripheral.xme" show="embed" type="simple"/> +</info> +</infoList> +</TargetConfig> + + diff --git a/lpc_chip_15xx/.gitignore b/lpc_chip_15xx/.gitignore new file mode 100644 index 0000000..3df573f --- /dev/null +++ b/lpc_chip_15xx/.gitignore @@ -0,0 +1 @@ +/Debug/ diff --git a/lpc_chip_15xx/.project b/lpc_chip_15xx/.project new file mode 100644 index 0000000..dec5b46 --- /dev/null +++ b/lpc_chip_15xx/.project @@ -0,0 +1,26 @@ + + + lpc_chip_15xx + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/lpc_chip_15xx/.settings/language.settings.xml b/lpc_chip_15xx/.settings/language.settings.xml new file mode 100644 index 0000000..168be13 --- /dev/null +++ b/lpc_chip_15xx/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lpc_chip_15xx/inc/acmp_15xx.h b/lpc_chip_15xx/inc/acmp_15xx.h new file mode 100644 index 0000000..9f47794 --- /dev/null +++ b/lpc_chip_15xx/inc/acmp_15xx.h @@ -0,0 +1,490 @@ +/* + * @brief LPC15xx Analog comparator driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ACMP_15XX_H_ +#define __ACMP_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ACMP_15XX CHIP: LPC15xx Analog Comparator driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief Analog Comparator channel register block structure + */ +typedef struct { + __IO uint32_t CMP; /*!< Individual Comparator control register */ + __IO uint32_t CMPFILTR; /*!< Individual Comparator Filter registers */ +} CMP_REG_T; + +/** + * @brief Analog Comparator register block structure + */ +typedef struct { /*!< ACMP Structure */ + __IO uint32_t CTRL; /*!< Comparator block control register */ + __IO CMP_REG_T ACMP[4]; /*!< Individual Comparator registers */ +} LPC_CMP_T; + +/* Bit definitions for block control register */ +#define ACMP_ROSCCTL_BIT (1 << 8) /* Ring Oscillator control bit */ +#define ACMP_EXTRESET_BIT (1 << 9) /* Reset source for ring oscillator 0 - Internal, 1 - External pin */ + +/* Bit definitions for compare register */ +#define ACMP_CMPEN_BIT (1 << 0) /* Comparator enable bit */ +#define ACMP_INTEN_BIT (1 << 2) /* Comparator Interrupt enable bit */ +#define ACMP_STATUS_BIT (1 << 3) /* Comparator status, reflects the state of the comparator output */ +#define ACMP_COMPVMSEL_MASK (0x7 << 4) /* Mask for VM Input selection */ +#define ACMP_COMPVPSEL_MASK (0x7 << 8) /* Mask for VP Input selection */ +#define ACMP_HYSTERESIS_MASK (0x3 << 13) /* Mask for Hysterisis Control */ +#define ACMP_INTPOL_BIT (1 << 15) /* Polarity of CMP output for interrupt 0 - Not Inverted, 1 - Inverted */ +#define ACMP_INTTYPE_BIT (1 << 16) /* Interrupt Type 0 - Edge, 1 - Level */ +#define ACMP_INTEDGE_MASK (0x3 << 17) /* Mask for Interrupt edge selection */ +#define ACMP_INTFLAG_BIT (1 << 19) /* Interrupt Flag bit */ +#define ACMP_LADENAB_BIT (1 << 20) /* Voltage ladder enable bit */ +#define ACMP_LADREF_BIT (1 << 22) /* Voltage reference select bit for voltage ladder */ +#define ACMP_LADSEL_MASK (0x1F << 24) /* Reference voltage selection mask for ladder */ +#define ACMP_PROPDLY_MASK (0x3 << 29) /* Propogation delay mask */ + +/* Bit definitions for comparator filter register */ +#define ACMP_SMODE_MASK (0x3 << 0) /* Mask for digital filter sample mode */ +#define ACMP_CLKDIV_MASK (0x7 << 2) /* Mask for comparator clock */ + +/** Edge selection for comparator */ +typedef enum { + ACMP_EDGESEL_FALLING = (0 << 17), /* Set the COMPEDGE bit on falling edge */ + ACMP_EDGESEL_RISING = (1 << 17), /* Set the COMPEDGE bit on rising edge */ + ACMP_EDGESEL_BOTH = (2 << 17) /* Set the COMPEDGE bit on falling and rising edges */ +} CHIP_ACMP_EDGESEL_T; + +/** Hysteresis selection for comparator */ +typedef enum { + ACMP_HYS_NONE = (0 << 13), /* No hysteresis (the output will switch as the voltages cross) */ + ACMP_HYS_5MV = (1 << 13), /* 5mV hysteresis */ + ACMP_HYS_10MV = (2 << 13), /* 10mV hysteresis */ + ACMP_HYS_15MV = (3 << 13) /* 20mV hysteresis */ +} CHIP_ACMP_HYS_T; + +/** + * Analog Comparator positive input values + */ +typedef enum CHIP_ACMP_POS_INPUT { + ACMP_POSIN_VREF_DIV = (0 << 8), /*!< Voltage ladder output */ + ACMP_POSIN_ACMP_I1 = (1 << 8), /*!< ACMP_I1 pin */ + ACMP_POSIN_ACMP_I2 = (2 << 8), /*!< ACMP_I2 pin */ + ACMP_POSIN_ACMP_I3 = (3 << 8), /*!< ACMP_I3 pin */ + ACMP_POSIN_ACMP_I4 = (4 << 8), /*!< ACMP_I4 pin */ + ACMP_POSIN_INT_REF = (5 << 8), /*!< Internal reference voltage */ + ACMP_POSIN_ADCIN_1 = (6 << 8), /*!< ADC Input or Temperature sensor varies with comparator */ + ACMP_POSIN_ADCIN_2 = (7 << 8) /*!< ADC Input varies with comparator */ +} CHIP_ACMP_POS_INPUT_T; + +/** + * Analog Comparator negative input values + */ +typedef enum CHIP_ACMP_NEG_INPUT { + ACMP_NEGIN_VREF_DIV = (0 << 4), /*!< Voltage ladder output */ + ACMP_NEGIN_ACMP_I1 = (1 << 4), /*!< ACMP_I1 pin */ + ACMP_NEGIN_ACMP_I2 = (2 << 4), /*!< ACMP_I2 pin */ + ACMP_NEGIN_ACMP_I3 = (3 << 4), /*!< ACMP_I3 pin */ + ACMP_NEGIN_ACMP_I4 = (4 << 4), /*!< ACMP_I4 pin */ + ACMP_NEGIN_INT_REF = (5 << 4), /*!< Internal reference voltage */ + ACMP_NEGIN_ADCIN_1 = (6 << 4), /*!< ADC Input or Temperature sensor varies with comparator */ + ACMP_NEGIN_ADCIN_2 = (7 << 4) /*!< ADC Input varies with comparator */ +} CHIP_ACMP_NEG_INPUT_T; + +/** + * Analog Comparator sample mode values + */ +typedef enum { + ACMP_SMODE_0 = 0, /*!< Bypass filter */ + ACMP_SMODE_1, /*!< Reject pulses shorter than 1 filter clock cycle */ + ACMP_SMODE_2, /*!< Reject pulses shorter than 2 filter clock cycle */ + ACMP_SMODE_3 /*!< Reject pulses shorter than 3 filter clock cycle */ +} CHIP_ACMP_SMODE_T; + +/** + * Analog Comparator clock divider values + */ +typedef enum { + ACMP_CLKDIV_1 = (0x0 << 2), /*!< Use CMP_PCLK */ + ACMP_CLKDIV_2 = (0x1 << 2), /*!< Use CMP_PCLK/2 */ + ACMP_CLKDIV_4 = (0x2 << 2), /*!< Use CMP_PCLK/4 */ + ACMP_CLKDIV_8 = (0x3 << 2), /*!< Use CMP_PCLK/8 */ + ACMP_CLKDIV_16 = (0x4 << 2), /*!< Use CMP_PCLK/16 */ + ACMP_CLKDIV_32 = (0x5 << 2), /*!< Use CMP_PCLK/32 */ + ACMP_CLKDIV_64 = (0x6 << 2) /*!< Use CMP_PCLK/64 */ +} CHIP_ACMP_CLKDIV_T; + +/** + * @brief Initializes the ACMP + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +void Chip_ACMP_Init(LPC_CMP_T *pACMP); + +/** + * @brief Deinitializes the ACMP + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +void Chip_ACMP_Deinit(LPC_CMP_T *pACMP); + +/** + * @brief Enable the comparator + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_EnableComp(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_CMPEN_BIT; +} + +/** + * @brief Disable the comparator + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_DisableComp(LPC_CMP_T *pACMP, uint8_t index) +{ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_CMPEN_BIT; +} + +/** + * @brief Enable the interrupt for the comparator + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_EnableCompInt(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTEN_BIT; +} + +/** + * @brief Disable the interrupt for the comparator + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_DisableCompInt(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTEN_BIT; +} + +/** + * @brief Returns the current comparator status + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return TRUE if ACMP_STATUS_BIT is set else returns FALSE + */ +STATIC INLINE bool Chip_ACMP_GetCompStatus(LPC_CMP_T *pACMP, uint8_t index) +{ + return (pACMP->ACMP[index].CMP & ACMP_STATUS_BIT) != 0; +} + +/** + * @brief Selects positive voltage input + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param Posinput: one of the positive input voltage sources + * @return Nothing + */ +void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_POS_INPUT_T Posinput); + +/** + * @brief Selects negative voltage input + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param Neginput: one of the negative input voltage sources + * @return Nothing + */ +void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_NEG_INPUT_T Neginput); + +/** + * @brief Selects hysteresis level + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param hys : Selected Hysteresis level + * @return Nothing + */ +void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_HYS_T hys); + +/** + * @brief Set the ACMP interrupt polarity (INTPOL bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetIntPolarity(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTPOL_BIT; +} + +/** + * @brief Clear the ACMP interrupt polarity (INTPOL bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_ClearIntPolarity(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTPOL_BIT; +} + +/** + * @brief Set the ACMP interrupt type as edge (INTTYPE bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetIntTypeEdge(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTTYPE_BIT; +} + +/** + * @brief Set the ACMP interrupt type as level (INTTYPE bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetIntTypeLevel(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTTYPE_BIT; +} + +/** + * @brief Sets up ACMP edge selection + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param edgeSel : Edge selection value + * @return Nothing + */ +void Chip_ACMP_SetIntEdgeSelection(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_EDGESEL_T edgeSel); + +/** + * @brief Get the ACMP interrupt flag bit(INTFLAG bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return TRUE if ACMP_INTFLAG_BIT is set else returns FALSE + */ +STATIC INLINE bool Chip_ACMP_GetIntFlag(LPC_CMP_T *pACMP, uint8_t index) +{ + return (pACMP->ACMP[index].CMP & ACMP_INTFLAG_BIT) != 0; +} + +/** + * @brief Clears the ACMP interrupt flag bit (INTFLAG bit) + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_ClearIntFlag(LPC_CMP_T *pACMP, uint8_t index) +{ + pACMP->ACMP[index].CMP |= ACMP_INTFLAG_BIT; +} + +/** + * @brief Helper function for setting up ACMP voltage settings + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param Posinput : one of the positive input voltage sources + * @param Neginput : one of the negative input voltage sources + * @param hys : Selected Hysteresis level + * @return Nothing + */ +void Chip_ACMP_SetupACMPRefs(LPC_CMP_T *pACMP, uint8_t index, + CHIP_ACMP_POS_INPUT_T Posinput, CHIP_ACMP_NEG_INPUT_T Neginput, + CHIP_ACMP_HYS_T hys); + +/** + * @brief Helper function for setting up ACMP interrupt settings + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param level : interrupt type false - edge, true - level + * @param invert : polarity of CMP output for interrupt, false - Not Inverted, true - Inverted + * @param edgeSel : Edge selection value + * @return Nothing + */ +void Chip_ACMP_SetupACMPInt(LPC_CMP_T *pACMP, uint8_t index, bool level, + bool invert, CHIP_ACMP_EDGESEL_T edgeSel); + +/** + * @brief Sets up voltage ladder + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param ladsel : Voltage ladder value (0 .. 31) + * @param ladrefVDDCMP : Selects the reference voltage Vref for the voltage ladder + * true for VDD, false for VDDCMP pin + * @return Nothing + */ +void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint8_t index, uint32_t ladsel, bool ladrefVDDCMP); + +/** + * @brief Enables voltage ladder + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_EnableVoltLadder(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_LADENAB_BIT; +} + +/** + * @brief Disables voltage ladder + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_DisableVoltLadder(LPC_CMP_T *pACMP, uint8_t index) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_LADENAB_BIT; +} + +/** + * @brief Set propogation delay for comparator output + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param delay : propogation delay (0 - 2), 0 is short delay more power consumption + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetPropagationDelay(LPC_CMP_T *pACMP, uint8_t index, uint8_t delay) +{ + /* Make sure interrupt flag is not set during read write operation */ + pACMP->ACMP[index].CMP = + ((pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_PROPDLY_MASK) | ((uint32_t) delay << 29); +} + +/** + * @brief Set filter sample mode + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param mode : sample mode enum value + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetSampleMode(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_SMODE_T mode) +{ + pACMP->ACMP[index].CMPFILTR = (pACMP->ACMP[index].CMPFILTR & ~ACMP_SMODE_MASK) | (uint32_t) mode; +} + +/** + * @brief Set clock divider + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param div : SysClk divider enum value + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetClockDiv(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_CLKDIV_T div) +{ + pACMP->ACMP[index].CMPFILTR = (pACMP->ACMP[index].CMPFILTR & ~ACMP_CLKDIV_MASK) | (uint32_t) div; +} + +/** + * @brief Setup Comparator filter register + * @param pACMP : Pointer to Analog Comparator block + * @param index : index to the comparator (0 - 3) + * @param mode : sample mode enum value + * @param div : SysClk divider enum value + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetCompFiltReg(LPC_CMP_T *pACMP, + uint8_t index, + CHIP_ACMP_SMODE_T mode, + CHIP_ACMP_CLKDIV_T div) +{ + pACMP->ACMP[index].CMPFILTR = (uint32_t) mode | (uint32_t) div; +} + +/** + * @brief Set Ring Oscillator control bit, ROSC output is set by ACMP1 and reset by ACMP0 + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetRingOscCtl(LPC_CMP_T *pACMP) +{ + pACMP->CTRL |= ACMP_ROSCCTL_BIT; +} + +/** + * @brief Clear Ring Oscillator control bit, ROSC output is set by ACMP0 and reset by ACMP1 + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_ClearRingOscCtl(LPC_CMP_T *pACMP) +{ + pACMP->CTRL &= ~ACMP_ROSCCTL_BIT; +} + +/** + * @brief Set Ring Oscillator Reset Source to Internal + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetROscResetSrcInternal(LPC_CMP_T *pACMP) +{ + pACMP->CTRL &= ~ACMP_EXTRESET_BIT; +} + +/** + * @brief Set Ring Oscillator Reset Source to External + * @param pACMP : Pointer to Analog Comparator block + * @return Nothing + */ +STATIC INLINE void Chip_ACMP_SetROscResetSrcExternal(LPC_CMP_T *pACMP) +{ + pACMP->CTRL |= ACMP_EXTRESET_BIT; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ACMP_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/adc_15xx.h b/lpc_chip_15xx/inc/adc_15xx.h new file mode 100644 index 0000000..c5abbef --- /dev/null +++ b/lpc_chip_15xx/inc/adc_15xx.h @@ -0,0 +1,597 @@ +/* + * @brief LPC15xx ADC driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ADC_15XX_H_ +#define __ADC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ADC_15XX CHIP: LPC15xx A/D conversion driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** Sequence index enumerations, used in various parts of the code for + register indexing and sequencer selection */ +typedef enum { + ADC_SEQA_IDX, + ADC_SEQB_IDX +} ADC_SEQ_IDX_T; + +/** + * @brief ADC register block structure + */ +typedef struct { /*!< ADCn Structure */ + __IO uint32_t CTRL; /*!< A/D Control Register. The AD0CR register must be written to select the operating mode before A/D conversion can occur. */ + __IO uint32_t INSEL; /*!< A/D Input Select Register. This field selects the input source for channel 0. */ + __IO uint32_t SEQ_CTRL[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Control Register. Controls triggering and channel selection for sonversion sequence. */ + __IO uint32_t SEQ_GDAT[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Global Data Register. Contains the result of the most recent A/D conversion for sequence. */ + __I uint32_t RESERVED1[2]; + __I uint32_t DR[12]; /*!< A/D Channel Data Register. This register contains the result of the most recent conversion completed on channel n. */ + __IO uint32_t THR_LOW[2]; /*!< A/D Low Compare Threshold Register 0 & 1. Contains the lower threshold level for automatic threshold comparison. */ + __IO uint32_t THR_HIGH[2]; /*!< A/D High Compare Threshold Register 0 & 1. Contains the higher threshold level for automatic threshold comparison. */ + __IO uint32_t CHAN_THRSEL; /*!< A/D Channel Threshold Select Register. Specifies which set of threshold compare registers to use. */ + __IO uint32_t INTEN; /*!< A/D Interrupt Enable Register. This register contains enable bits that enable sequence-A, sequence-B, threshold compare and overrun interrupts. */ + __IO uint32_t FLAGS; /*!< A/D Flags Register. This register contains interrupt flags. - To be checked */ + __IO uint32_t TRM; /*!< A/D Trim Register. */ +} LPC_ADC_T; + +/** Maximum sample rate in Hz (12-bit conversions) */ +#define ADC_MAX_SAMPLE_RATE 50000000 + +/** + * @brief ADC register support bitfields and mask + */ +/** ADC Control register bit fields */ +#define ADC_CR_CLKDIV_MASK (0xFF << 0) /*!< Mask for Clock divider value */ +#define ADC_CR_CLKDIV_BITPOS (0) /*!< Bit position for Clock divider value */ +#define ADC_CR_ASYNMODE (1 << 8) /*!< Asynchronous mode enable bit */ +#define ADC_CR_MODE10BIT (1 << 9) /*!< 10-bit mode enable bit */ +#define ADC_CR_LPWRMODEBIT (1 << 10) /*!< Low power mode enable bit */ +#define ADC_CR_CALMODEBIT (1 << 30) /*!< Self calibration cycle enable bit */ +#define ADC_CR_BITACC(n) ((((n) & 0x1) << 9)) /*!< 12-bit or 10-bit ADC accuracy */ +#define ADC_CR_CLKDIV(n) ((((n) & 0xFF) << 0)) /*!< The APB clock (PCLK) is divided by (this value plus one) to produce the clock for the A/D */ +#define ADC_SAMPLE_RATE_CONFIG_MASK (ADC_CR_CLKDIV(0xFF) | ADC_CR_BITACC(0x01)) + +/** ADC input select register */ +#define ADC_INSEL_ADC0 (0x0 << 0) /*!< Select ADCn_0 for channel 0 */ +#define ADC_INSEL_CRVO (0x1 << 0) /*!< Selects the Core voltage regulator output for channel 0 */ +#define ADC_INSEL_IVR (0x2 << 0) /*!< Selects the Internal voltage reference for channel 0 */ +#define ADC_INSEL_TS (0x3 << 0) /*!< Selects the Temperature Sensor for channel 0 */ +#define ADC_INSEL_VDDA_DIV (0x4 << 0) /*!< Selects VDDA/2 for channel 0 */ + +/** ADC Sequence Control register bit fields */ +#define ADC_SEQ_CTRL_CHANSEL(n) (1 << (n)) /*!< Channel select macro */ +#define ADC_SEQ_CTRL_CHANSEL_MASK (0xFFF) /*!< Channel select mask */ + +/** ADC hardware trigger sources in SEQ_CTRL for ADC0 only. These sources should + * only be used when selecting trigger sources for ADC0. */ +#define ADC0_SEQ_CTRL_HWTRIG_ADC0_PIN_TRIG0 (0 << 12) /*!< HW trigger input - ADC0_PIN_TRIG0 */ +#define ADC0_SEQ_CTRL_HWTRIG_ADC0_PIN_TRIG1 (1 << 12) /*!< HW trigger input - ADC0_PIN_TRIG1 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT0_OUT7 (2 << 12) /*!< HW trigger input - SCT0_OUT7 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT0_OUT9 (3 << 12) /*!< HW trigger input - SCT0_OUT9 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT1_OUT7 (4 << 12) /*!< HW trigger input - SCT1_OUT7 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT1_OUT9 (5 << 12) /*!< HW trigger input - SCT1_OUT9 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT2_OUT3 (6 << 12) /*!< HW trigger input - SCT2_OUT3 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT2_OUT4 (7 << 12) /*!< HW trigger input - SCT2_OUT4 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT3_OUT3 (8 << 12) /*!< HW trigger input - SCT3_OUT3 */ +#define ADC0_SEQ_CTRL_HWTRIG_SCT3_OUT4 (9 << 12) /*!< HW trigger input - SCT3_OUT4 */ +#define ADC0_SEQ_CTRL_HWTRIG_ACMP0_O (10 << 12) /*!< HW trigger input - ACMP0_O */ +#define ADC0_SEQ_CTRL_HWTRIG_ACMP1_O (11 << 12) /*!< HW trigger input - ACMP1_O */ +#define ADC0_SEQ_CTRL_HWTRIG_ACMP2_O (12 << 12) /*!< HW trigger input - ACMP2_O */ +#define ADC0_SEQ_CTRL_HWTRIG_ACMP3_O (13 << 12) /*!< HW trigger input - ACMP3_O */ +#define ADC0_SEQ_CTRL_HWTRIG_MASK (0x3F << 12) /*!< HW trigger input bitfield mask */ + +/** ADC hardware trigger sources in SEQ_CTRL for ADC1 only. These sources should + * only be used when selecting trigger sources for ADC1. */ +#define ADC1_SEQ_CTRL_HWTRIG_ADC1_PIN_TRIG0 (0 << 12) /*!< HW trigger input - ADC1_PIN_TRIG0 */ +#define ADC1_SEQ_CTRL_HWTRIG_ADC1_PIN_TRIG1 (1 << 12) /*!< HW trigger input - ADC1_PIN_TRIG1 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT0_OUT6 (2 << 12) /*!< HW trigger input - SCT0_OUT6 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT0_OUT9 (3 << 12) /*!< HW trigger input - SCT0_OUT9 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT1_OUT8 (4 << 12) /*!< HW trigger input - SCT1_OUT8 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT1_OUT9 (5 << 12) /*!< HW trigger input - SCT1_OUT9 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT2_OUT2 (6 << 12) /*!< HW trigger input - SCT2_OUT2 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT2_OUT5 (7 << 12) /*!< HW trigger input - SCT2_OUT5 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT3_OUT2 (8 << 12) /*!< HW trigger input - SCT3_OUT2 */ +#define ADC1_SEQ_CTRL_HWTRIG_SCT3_OUT5 (9 << 12) /*!< HW trigger input - SCT3_OUT5 */ +#define ADC1_SEQ_CTRL_HWTRIG_ACMP0_O (10 << 12) /*!< HW trigger input - ACMP0_O */ +#define ADC1_SEQ_CTRL_HWTRIG_ACMP1_O (11 << 12) /*!< HW trigger input - ACMP1_O */ +#define ADC1_SEQ_CTRL_HWTRIG_ACMP2_O (12 << 12) /*!< HW trigger input - ACMP2_O */ +#define ADC1_SEQ_CTRL_HWTRIG_ACMP3_O (13 << 12) /*!< HW trigger input - ACMP3_O */ +#define ADC1_SEQ_CTRL_HWTRIG_MASK (0x3F << 12) /*!< HW trigger input bitfield mask */ + +/** SEQ_CTRL register bit fields */ +#define ADC_SEQ_CTRL_HWTRIG_POLPOS (1 << 18) /*!< HW trigger polarity - positive edge */ +#define ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS (1 << 19) /*!< HW trigger bypass synchronisation */ +#define ADC_SEQ_CTRL_START (1 << 26) /*!< Start conversion enable bit */ +#define ADC_SEQ_CTRL_BURST (1 << 27) /*!< Repeated conversion enable bit */ +#define ADC_SEQ_CTRL_SINGLESTEP (1 << 28) /*!< Single step enable bit */ +#define ADC_SEQ_CTRL_LOWPRIO (1 << 29) /*!< High priority enable bit (regardless of name) */ +#define ADC_SEQ_CTRL_MODE_EOS (1 << 30) /*!< Mode End of sequence enable bit */ +#define ADC_SEQ_CTRL_SEQ_ENA (1UL << 31) /*!< Sequence enable bit */ + +/** ADC global data register bit fields */ +#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF << 4) /*!< Result value mask */ +#define ADC_SEQ_GDAT_RESULT_BITPOS (4) /*!< Result start bit position */ +#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */ +#define ADC_SEQ_GDAT_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */ +#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */ +#define ADC_SEQ_GDAT_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */ +#define ADC_SEQ_GDAT_CHAN_MASK (0xF << 26) /*!< Channel number mask */ +#define ADC_SEQ_GDAT_CHAN_BITPOS (26) /*!< Channel number bit position */ +#define ADC_SEQ_GDAT_OVERRUN (1 << 30) /*!< Overrun bit */ +#define ADC_SEQ_GDAT_DATAVALID (1UL << 31) /*!< Data valid bit */ + +/** ADC Data register bit fields */ +#define ADC_DR_RESULT(n) ((((n) >> 4) & 0xFFF)) /*!< Macro for getting the ADC data value */ +#define ADC_DR_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */ +#define ADC_DR_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */ +#define ADC_DR_THCMPRANGE(n) (((n) >> ADC_DR_THCMPRANGE_BITPOS) & 0x3) +#define ADC_DR_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */ +#define ADC_DR_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */ +#define ADC_DR_THCMPCROSS(n) (((n) >> ADC_DR_THCMPCROSS_BITPOS) & 0x3) +#define ADC_DR_CHAN_MASK (0xF << 26) /*!< Channel number mask */ +#define ADC_DR_CHAN_BITPOS (26) /*!< Channel number bit position */ +#define ADC_DR_CHANNEL(n) (((n) >> ADC_DR_CHAN_BITPOS) & 0xF) /*!< Channel number bit position */ +#define ADC_DR_OVERRUN (1 << 30) /*!< Overrun bit */ +#define ADC_DR_DATAVALID (1UL << 31) /*!< Data valid bit */ +#define ADC_DR_DONE(n) (((n) >> 31)) + +/** ADC low/high Threshold register bit fields */ +#define ADC_THR_VAL_MASK (0xFFF << 4) /*!< Threshold value bit mask */ +#define ADC_THR_VAL_POS (4) /*!< Threshold value bit position */ + +/** ADC Threshold select register bit fields */ +#define ADC_THRSEL_CHAN_SEL_THR1(n) (1 << (n)) /*!< Select THR1 register for channel n */ + +/** ADC Interrupt Enable register bit fields */ +#define ADC_INTEN_SEQA_ENABLE (1 << 0) /*!< Sequence A Interrupt enable bit */ +#define ADC_INTEN_SEQB_ENABLE (1 << 1) /*!< Sequence B Interrupt enable bit */ +#define ADC_INTEN_SEQN_ENABLE(seq) (1 << (seq)) /*!< Sequence A/B Interrupt enable bit */ +#define ADC_INTEN_OVRRUN_ENABLE (1 << 2) /*!< Overrun Interrupt enable bit */ +#define ADC_INTEN_CMP_DISBALE (0) /*!< Disable comparison interrupt value */ +#define ADC_INTEN_CMP_OUTSIDETH (1) /*!< Outside threshold interrupt value */ +#define ADC_INTEN_CMP_CROSSTH (2) /*!< Crossing threshold interrupt value */ +#define ADC_INTEN_CMP_MASK (3) /*!< Comparison interrupt value mask */ +#define ADC_INTEN_CMP_ENABLE(isel, ch) (((isel) & ADC_INTEN_CMP_MASK) << ((2 * (ch)) + 3)) /*!< Interrupt selection for channel */ + +/** ADC Flags register bit fields */ +#define ADC_FLAGS_THCMP_MASK(ch) (1 << (ch)) /*!< Threshold comparison status for channel */ +#define ADC_FLAGS_OVRRUN_MASK(ch) (1 << (12 + (ch))) /*!< Overrun status for channel */ +#define ADC_FLAGS_SEQA_OVRRUN_MASK (1 << 24) /*!< Seq A Overrun status */ +#define ADC_FLAGS_SEQB_OVRRUN_MASK (1 << 25) /*!< Seq B Overrun status */ +#define ADC_FLAGS_SEQN_OVRRUN_MASK(seq) (1 << (24 + (seq))) /*!< Seq A/B Overrun status */ +#define ADC_FLAGS_SEQA_INT_MASK (1 << 28) /*!< Seq A Interrupt status */ +#define ADC_FLAGS_SEQB_INT_MASK (1 << 29) /*!< Seq B Interrupt status */ +#define ADC_FLAGS_SEQN_INT_MASK(seq) (1 << (28 + (seq)))/*!< Seq A/B Interrupt status */ +#define ADC_FLAGS_THCMP_INT_MASK (1 << 30) /*!< Threshold comparison Interrupt status */ +#define ADC_FLAGS_OVRRUN_INT_MASK (1UL << 31) /*!< Overrun Interrupt status */ + +/** ADC Trim register bit fields */ +#define ADC_TRIM_VRANGE_HIGHV (0 << 5) /*!< Voltage range bit - High volatge (2.7V to 3.6V) */ +#define ADC_TRIM_VRANGE_LOWV (1 << 5) /*!< Voltage range bit - Low volatge (1.8V to 2.7V) */ + +/** + * @brief Initialize the ADC peripheral + * @param pADC : The base of ADC peripheral on the chip + * @param flags : ADC flags for init (ADC_CR_MODE10BIT and/or ADC_CR_LPWRMODEBIT) + * @return Nothing + * @note To select low-power ADC mode, enable the ADC_CR_LPWRMODEBIT flag. + * To select 10-bit conversion mode, enable the ADC_CR_MODE10BIT flag. You ca + * also enable asychronous clock mode by using the ADC_CR_ASYNMODE. + * Example: Chip_ADC_Init(LPC_ADC, (ADC_CR_MODE10BIT | ADC_CR_LPWRMODEBIT)); + */ +void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags); + +/** + * @brief Shutdown ADC + * @param pADC : The base of ADC peripheral on the chip + * @return Nothing + * @note Disables the ADC clocks and ADC power + */ +void Chip_ADC_DeInit(LPC_ADC_T *pADC); + +/** + * @brief Set ADC divider + * @param pADC : The base of ADC peripheral on the chip + * @param div : ADC divider value to set minus 1 + * @return Nothing + * @note The value is used as a divider to generate the ADC + * clock rate from the ADC input clock. The ADC input clock is based + * on the system clock. Valid values for this function are from 0 to 255 + * with 0=divide by 1, 1=divide by 2, 2=divide by 3, etc.
+ * Do not decrement this value by 1.
+ * To set the ADC clock rate to 1MHz, use the following function:
+ * Chip_ADC_SetDivider(LPC_ADC, (Chip_Clock_GetSystemClockRate() / 1000000) - 1); + */ +STATIC INLINE void Chip_ADC_SetDivider(LPC_ADC_T *pADC, uint8_t div) +{ + uint32_t temp; + + temp = pADC->CTRL & ~(ADC_CR_CLKDIV_MASK); + pADC->CTRL = temp | (uint32_t) div; +} + +/** + * @brief Set ADC clock rate + * @param pADC : The base of ADC peripheral on the chip + * @param rate : rate in Hz to set ADC clock to (maximum ADC_MAX_SAMPLE_RATE) + * @return Nothing + * @note This function will not work if the ADC is used with the ASYNC + * ADC clock (set when the ADC_CR_ASYNMODE bit is on in the ADC CTRL register). + */ +void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate); + +/** + * @brief Get ADC divider + * @param pADC : The base of ADC peripheral on the chip + * @return the current ADC divider + * @note This function returns the divider that is used to generate the + * ADC frequency. The returned value must be incremented by 1. The + * frequency can be determined with the following function:
+ * adc_freq = Chip_Clock_GetSystemClockRate() / (Chip_ADC_GetDivider(LPC_ADC) + 1); + */ +STATIC INLINE uint8_t Chip_ADC_GetDivider(LPC_ADC_T *pADC) +{ + return pADC->CTRL & ADC_CR_CLKDIV_MASK; +} + +/** + * @brief Start ADC calibration + * @param pADC : The base of ADC peripheral on the chip + * @return Nothing + * @note Calibration is not done as part of Chip_ADC_Init(), but + * is required after the call to Chip_ADC_Init() or after returning + * from a power-down state. Calibration may alter the ADC_CR_ASYNMODE + * and ADC_CR_LPWRMODEBIT flags ni the CTRL register. + */ +void Chip_ADC_StartCalibration(LPC_ADC_T *pADC); + +/** + * @brief Start ADC calibration + * @param pADC : The base of ADC peripheral on the chip + * @return TRUE if calibration is complete, otherwise FALSE. + */ +STATIC INLINE bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC) +{ + return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0); +} + +/** + * @brief Select input select for ADC channel 0 + * @param pADC : The base of ADC peripheral on the chip + * @param inp : Select an ADC_INSEL_* value for ADC0 input selection + * @return Nothing + */ +STATIC INLINE void Chip_ADC_SetADC0Input(LPC_ADC_T *pADC, uint32_t inp) +{ + pADC->INSEL = inp; +} + +/** + * @brief Helper function for safely setting ADC sequencer register bits + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to set bits for + * @param bits : Or'ed bits of a sequencer register to set + * @return Nothing + * @note This function will safely set the ADC sequencer register bits + * while maintaining bits 20..25 as 0, regardless of the read state of those bits. + */ +void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits); + +/** + * @brief Helper function for safely clearing ADC sequencer register bits + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to clear bits for + * @param bits : Or'ed bits of a sequencer register to clear + * @return Nothing + * @note This function will safely clear the ADC sequencer register bits + * while maintaining bits 20..25 as 0, regardless of the read state of those bits. + */ +void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits); + +/** + * @brief Sets up ADC conversion sequencer A or B + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to setup + * @param options : OR'ed Sequencer options to setup (see notes) + * @return Nothing + * @note Sets up sequencer options for a conversion sequence. This function + * should be used to setup the selected channels for the sequence, the sequencer + * trigger, the trigger polarity, synchronization bypass, priority, and mode. All + * options are passed to the functions as a OR'ed list of values. This function will + * disable/clear the sequencer start/burst/single step/enable if they are enabled.
+ * Select the channels by OR'ing in one or more ADC_SEQ_CTRL_CHANSEL(ch) values.
+ * Select the hardware trigger by OR'ing in one ADC_SEQ_CTRL_HWTRIG_* value.
+ * Select a positive edge hardware trigger by OR'ing in ADC_SEQ_CTRL_HWTRIG_POLPOS.
+ * Select trigger bypass synchronisation by OR'ing in ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS.
+ * Select ADC single step on trigger/start by OR'ing in ADC_SEQ_CTRL_SINGLESTEP.
+ * Select higher priority conversion on the other sequencer by OR'ing in ADC_SEQ_CTRL_LOWPRIO.
+ * Select end of seqeuence instead of end of conversion interrupt by OR'ing in ADC_SEQ_CTRL_MODE_EOS.
+ * Example for setting up sequencer A (channels 0-2, trigger on high edge of PIO0_2, interrupt on end of sequence):
+ * Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, ( + * ADC_SEQ_CTRL_CHANSEL(0) | ADC_SEQ_CTRL_CHANSEL(1) | ADC_SEQ_CTRL_CHANSEL(2) | + * ADC_SEQ_CTRL_HWTRIG_PIO0_2 | ADC_SEQ_CTRL_HWTRIG_POLPOS | ADC_SEQ_CTRL_MODE_EOS)); + */ +STATIC INLINE void Chip_ADC_SetupSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t options) +{ + pADC->SEQ_CTRL[seqIndex] = options; +} + +/** + * @brief Enables a sequencer + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to enable + * @return Nothing + */ +STATIC INLINE void Chip_ADC_EnableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA); +} + +/** + * @brief Disables a sequencer + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to disable + * @return Nothing + */ +STATIC INLINE void Chip_ADC_DisableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA); +} + +/** + * @brief Forces a sequencer trigger event (software trigger of ADC) + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to start + * @return Nothing + * @note This function sets the START bit for the sequencer to force a + * single conversion sequence or a single step conversion. + */ +STATIC INLINE void Chip_ADC_StartSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_START); +} + +/** + * @brief Starts sequencer burst mode + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to start burst on + * @return Nothing + * @note This function sets the BURST bit for the sequencer to force + * continuous conversion. Use Chip_ADC_StopBurstSequencer() to stop the + * ADC burst sequence. + */ +STATIC INLINE void Chip_ADC_StartBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST); +} + +/** + * @brief Stops sequencer burst mode + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to stop burst on + * @return Nothing + */ +STATIC INLINE void Chip_ADC_StopBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST); +} + +/** ADC sequence global data register threshold comparison range enumerations */ +typedef enum { + ADC_DR_THCMPRANGE_INRANGE, + ADC_DR_THCMPRANGE_RESERVED, + ADC_DR_THCMPRANGE_BELOW, + ADC_DR_THCMPRANGE_ABOVE +} ADC_DR_THCMPRANGE_T; + +/** ADC sequence global data register threshold comparison cross enumerations */ +typedef enum { + ADC_DR_THCMPCROSS_NOCROSS, + ADC_DR_THCMPCROSS_RESERVED, + ADC_DR_THCMPCROSS_DOWNWARD, + ADC_DR_THCMPCROSS_UPWARD +} ADC_DR_THCMPCROSS_T; + +/** + * @brief Read a ADC sequence global data register + * @param pADC : The base of ADC peripheral on the chip + * @param seqIndex : Sequencer to read + * @return Current raw value of the ADC sequence A or B global data register + * @note This function returns the raw value of the data register and clears + * the overrun and datavalid status for the register. Once this register is read, + * the following functions can be used to parse the raw value:
+ * uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value + * uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value + * ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high + * ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low + * uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data + * bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag + * bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag + */ +STATIC INLINE uint32_t Chip_ADC_GetSequencerDataReg(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex) +{ + return pADC->SEQ_GDAT[seqIndex]; +} + +/** + * @brief Read a ADC data register + * @param pADC : The base of ADC peripheral on the chip + * @param index : Data register to read, 1-8 + * @return Current raw value of the ADC data register + * @note This function returns the raw value of the data register and clears + * the overrun and datavalid status for the register. Once this register is read, + * the following functions can be used to parse the raw value:
+ * uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value + * uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value + * ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high + * ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low + * uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data + * bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag + * bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag + */ +STATIC INLINE uint32_t Chip_ADC_GetDataReg(LPC_ADC_T *pADC, uint8_t index) +{ + return pADC->DR[index]; +} + +/** + * @brief Set Threshold low value in ADC + * @param pADC : The base of ADC peripheral on the chip + * @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0) + * @param value : Threshold low data value (should be 12-bit value) + * @return None + */ +STATIC INLINE void Chip_ADC_SetThrLowValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value) +{ + pADC->THR_LOW[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS); +} + +/** + * @brief Set Threshold high value in ADC + * @param pADC : The base of ADC peripheral on the chip + * @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0) + * @param value : Threshold high data value (should be 12-bit value) + * @return None + */ +STATIC INLINE void Chip_ADC_SetThrHighValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value) +{ + pADC->THR_HIGH[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS); +} + +/** + * @brief Select threshold 0 values for comparison for selected channels + * @param pADC : The base of ADC peripheral on the chip + * @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values + * @return None + * @note Select multiple channels to use the threshold 0 comparison.
+ * Example:
+ * Chip_ADC_SelectTH0Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(1) | ADC_THRSEL_CHAN_SEL_THR1(2))); // Selects channels 1 and 2 for threshold 0 + */ +void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels); + +/** + * @brief Select threshold 1 value for comparison for selected channels + * @param pADC : The base of ADC peripheral on the chip + * @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values + * @return None + * @note Select multiple channels to use the 1 threshold comparison.
+ * Example:
+ * Chip_ADC_SelectTH1Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(4) | ADC_THRSEL_CHAN_SEL_THR1(5))); // Selects channels 4 and 5 for 1 threshold + */ +void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels); + +/** + * @brief Enable interrupts in ADC (sequencers A/B and overrun) + * @param pADC : The base of ADC peripheral on the chip + * @param intMask : Interrupt values to be enabled (see notes) + * @return None + * @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE, + * ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to enable the + * specific ADC interrupts. + */ +void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask); + +/** + * @brief Disable interrupts in ADC (sequencers A/B and overrun) + * @param pADC : The base of ADC peripheral on the chip + * @param intMask : Interrupt values to be disabled (see notes) + * @return None + * @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE, + * ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to disable the + * specific ADC interrupts. + */ +void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask); + +/** Threshold interrupt event options */ +typedef enum { + ADC_INTEN_THCMP_DISABLE, + ADC_INTEN_THCMP_OUTSIDE, + ADC_INTEN_THCMP_CROSSING, +} ADC_INTEN_THCMP_T; + +/** + * @brief Enable a threshold event interrupt in ADC + * @param pADC : The base of ADC peripheral on the chip + * @param ch : ADC channel to set threshold inetrrupt for, 1-8 + * @param thInt : Selected threshold interrupt type + * @return None + */ +void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt); + +/** + * @brief Get flags register in ADC + * @param pADC : The base of ADC peripheral on the chip + * @return Flags register value (ORed ADC_FLAG* values) + * @note Mask the return value of this function with the ADC_FLAGS_* + * definitions to determine the overall ADC interrupt events.
+ * Example:
+ * if (Chip_ADC_GetFlags(LPC_ADC) & ADC_FLAGS_THCMP_MASK(3) // Check of threshold comp status for ADC channel 3 + */ +STATIC INLINE uint32_t Chip_ADC_GetFlags(LPC_ADC_T *pADC) +{ + return pADC->FLAGS; +} + +/** + * @brief Clear flags register in ADC + * @param pADC : The base of ADC peripheral on the chip + * @param flags : An Or'ed values of ADC_FLAGS_* values to clear + * @return Flags register value (ORed ADC_FLAG* values) + */ +STATIC INLINE void Chip_ADC_ClearFlags(LPC_ADC_T *pADC, uint32_t flags) +{ + pADC->FLAGS = flags; +} + +/** + * @brief Set Trim register in ADC + * @param pADC : The base of ADC peripheral on the chip + * @param trim : Trim value (ADC_TRIM_VRANGE_HIGHV or ADC_TRIM_VRANGE_LOWV) + * @return None + */ +STATIC INLINE void Chip_ADC_SetTrim(LPC_ADC_T *pADC, uint32_t trim) +{ + pADC->TRM = trim; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/chip.h b/lpc_chip_15xx/inc/chip.h new file mode 100644 index 0000000..96b9c48 --- /dev/null +++ b/lpc_chip_15xx/inc/chip.h @@ -0,0 +1,244 @@ +/* + * @brief LPC15xx basic chip inclusion file + * + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __CHIP_H_ +#define __CHIP_H_ + +#include "lpc_types.h" +#include "sys_config.h" +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CORE_M3 +#error CORE_M3 is not defined for the LPC15xx architecture +#error CORE_M3 should be defined as part of your compiler define list +#endif + +#if !defined(CHIP_LPC15XX) +#error CHIP_LPC15XX is not defined! +#endif + +/** @defgroup PERIPH_15XX_BASE CHIP: LPC15xx Peripheral addresses and register set declarations + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +#define LPC_ADC0_BASE 0x40000000 +#define LPC_DAC_BASE 0x40004000 +#define LPC_CMP_BASE 0x40008000 +#define LPC_INMUX_BASE 0x40014000 +#define LPC_RTC_BASE 0x40028000 +#define LPC_WWDT_BASE 0x4002C000 +#define LPC_SWM_BASE 0x40038000 +#define LPC_PMU_BASE 0x4003C000 +#define LPC_USART0_BASE 0x40040000 +#define LPC_USART1_BASE 0x40044000 +#define LPC_SPI0_BASE 0x40048000 +#define LPC_SPI1_BASE 0x4004C000 +#define LPC_I2C_BASE 0x40050000 +#define LPC_QEI_BASE 0x40058000 +#define LPC_SYSCTL_BASE 0x40074000 +#define LPC_ADC1_BASE 0x40080000 +#define LPC_MRT_BASE 0x400A0000 +#define LPC_PIN_INT_BASE 0x400A4000 +#define LPC_GPIO_GROUP_INT0_BASE 0x400A8000 +#define LPC_GPIO_GROUP_INT1_BASE 0x400AC000 +#define LPC_RITIMER_BASE 0x400B4000 +#define LPC_SCTIPU_BASE 0x400B8000 +#define LPC_FLASH_BASE 0x400BC000 +#define LPC_USART2_BASE 0x400C0000 +#define LPC_C_CAN0_BASE 0x400F0000 +#define LPC_IOCON_BASE 0x400F8000 +#define LPC_EEPROM_BASE 0x400FC000 +#define LPC_GPIO_PIN_INT_BASE 0x1C000000 +#define LPC_DMA_BASE 0x1C004000 +#define LPC_USB0_BASE 0x1C00C000 +#define LPC_CRC_BASE 0x1C010000 +#define LPC_SCTLARGE_0_BASE 0x1C018000 +#define LPC_SCTLARGE_1_BASE 0x1C01C000 +#define LPC_SCTSMALL_0_BASE 0x1C020000 +#define LPC_SCTSMALL_1_BASE 0x1C024000 + +#define LPC_PMU ((LPC_PMU_T *) LPC_PMU_BASE) +#define LPC_IOCON ((LPC_IOCON_T *) LPC_IOCON_BASE) +#define LPC_SYSCTL ((LPC_SYSCTL_T *) LPC_SYSCTL_BASE) +#define LPC_SYSCON ((LPC_SYSCTL_T *) LPC_SYSCTL_BASE) /* Alias for LPC_SYSCTL */ +#define LPC_GPIO ((LPC_GPIO_T *) LPC_GPIO_PIN_INT_BASE) +#define LPC_GPIOGROUP ((LPC_GPIOGROUPINT_T *) LPC_GPIO_GROUP_INT0_BASE) +#define LPC_GPIO_PIN_INT ((LPC_PIN_INT_T *) LPC_PIN_INT_BASE) +#define LPC_USART0 ((LPC_USART_T *) LPC_USART0_BASE) +#define LPC_USART1 ((LPC_USART_T *) LPC_USART1_BASE) +#define LPC_USART2 ((LPC_USART_T *) LPC_USART2_BASE) +#define LPC_I2C0 ((LPC_I2C_T *) LPC_I2C_BASE) +#define LPC_I2C ((LPC_I2C_T *) LPC_I2C_BASE) /* Alias for I2C0 */ +#define LPC_USB ((LPC_USB_T *) LPC_USB0_BASE) +#define LPC_ADC0 ((LPC_ADC_T *) LPC_ADC0_BASE) +#define LPC_ADC1 ((LPC_ADC_T *) LPC_ADC1_BASE) +#define LPC_SCTLARGE0 ((LPC_SCT_T *) LPC_SCTLARGE_0_BASE) +#define LPC_SCTLARGE1 ((LPC_SCT_T *) LPC_SCTLARGE_1_BASE) +#define LPC_SCTSMALL0 ((LPC_SCT_T *) LPC_SCTSMALL_0_BASE) +#define LPC_SCTSMALL1 ((LPC_SCT_T *) LPC_SCTSMALL_1_BASE) +#define LPC_SCT0 LPC_SCTLARGE0 +#define LPC_SCT1 LPC_SCTLARGE1 +#define LPC_SCT2 LPC_SCTSMALL0 +#define LPC_SCT3 LPC_SCTSMALL1 +#define LPC_RTC ((LPC_RTC_T *) LPC_RTC_BASE) +#define LPC_WWDT ((LPC_WWDT_T *) LPC_WWDT_BASE) +#define LPC_DMA ((LPC_DMA_T *) LPC_DMA_BASE) +#define LPC_CRC ((LPC_CRC_T *) LPC_CRC_BASE) +#define LPC_FMC ((LPC_FMC_T *) LPC_FLASH_BASE) +#define LPC_MRT ((LPC_MRT_T *) LPC_MRT_BASE) +#define LPC_SWM ((LPC_SWM_T *) LPC_SWM_BASE) +#define LPC_RITIMER ((LPC_RITIMER_T *) LPC_RITIMER_BASE) +#define LPC_INMUX ((LPC_INMUX_T *) LPC_INMUX_BASE) +#define LPC_SCTIPU ((LPC_SCTIPU_T *) LPC_SCTIPU_BASE) +#define LPC_CMP ((LPC_CMP_T *) LPC_CMP_BASE) +#define LPC_DAC ((LPC_DAC_T *) LPC_DAC_BASE) +#define LPC_SPI0 ((LPC_SPI_T *) LPC_SPI0_BASE) +#define LPC_SPI1 ((LPC_SPI_T *) LPC_SPI1_BASE) + +/** + * @} + */ + +/** @ingroup CHIP_15XX_DRIVER_OPTIONS + * @{ + */ + +/** + * @brief System oscillator rate + * This value is defined externally to the chip layer and contains + * the value in Hz for the external oscillator for the board. If using the + * internal oscillator, this rate can be 0. + */ +extern const uint32_t OscRateIn; + +/** + * @brief RTC oscillator rate + * This value is defined externally to the chip layer and contains + * the value in Hz for the RTC oscillator for the board. This is + * usually 32KHz (32768). If not using the RTC, this rate can be 0. + */ +extern const uint32_t RTCOscRateIn; + + +/** + * @} + */ + +/* Include order is important! */ +#include "romapi_15xx.h" +#include "sysctl_15xx.h" +#include "clock_15xx.h" +#include "iocon_15xx.h" +#include "swm_15xx.h" +#include "pmu_15xx.h" +#include "crc_15xx.h" +#include "gpio_15xx.h" +#include "pinint_15xx.h" +#include "gpiogroup_15xx.h" +#include "uart_15xx.h" +#include "adc_15xx.h" +#include "mrt_15xx.h" +#include "ritimer_15xx.h" +#include "dma_15xx.h" +#include "usbd_15xx.h" +#include "sctipu_15xx.h" +#include "sct_15xx.h" +#include "sct_pwm_15xx.h" +#include "rtc_15xx.h" +#include "wwdt_15xx.h" +#include "fmc_15xx.h" +#include "inmux_15xx.h" +#include "acmp_15xx.h" +#include "dac_15xx.h" +#include "spi_15xx.h" +#include "i2cm_15xx.h" +#include "i2cs_15xx.h" + +/** @defgroup SUPPORT_15XX_FUNC CHIP: LPC15xx support functions + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief Current system clock rate, mainly used for sysTick + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Update system core clock rate, should be called if the + * system has a clock rate change + * @return None + */ +void SystemCoreClockUpdate(void); + +/** + * @brief Set up and initialize hardware prior to call to main() + * @return None + * @note Chip_SystemInit() is called prior to the application and sets up + * system clocking prior to the application starting. + */ +void Chip_SystemInit(void); + +/** + * @brief USB clock initialization + * Calling this function will initialize the USB PLL and clock divider + * @return None + * @note This function will assume that the chip is clocked by an + * external crystal oscillator of frequency 12MHz and the Oscillator + * is running. + */ +void Chip_USB_Init(void); + +/** + * @brief Clock and PLL initialization based on the external oscillator + * @return None + * @note This function assumes an external crystal oscillator + * frequency of 12MHz. + */ +void Chip_SetupXtalClocking(void); + +/** + * @brief Clock and PLL initialization based on the internal oscillator + * @return None + */ +void Chip_SetupIrcClocking(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CHIP_H_ */ diff --git a/lpc_chip_15xx/inc/clock_15xx.h b/lpc_chip_15xx/inc/clock_15xx.h new file mode 100644 index 0000000..872e0cd --- /dev/null +++ b/lpc_chip_15xx/inc/clock_15xx.h @@ -0,0 +1,692 @@ +/* + * @brief LPC15XX Clock control functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __CLOCK_15XX_H_ +#define __CLOCK_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CLOCK_15XX CHIP: LPC15xx Clock Control block driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** Internal oscillator frequency */ +#define SYSCTL_IRC_FREQ (12000000) + +/** Internal watchdog oscillator frequency */ +#define SYSCTL_WDTOSC_FREQ (503000) + +/** @defgroup CLOCK_15XXcCHIP_SEL: Clock source selection functions + * These functions provide selection of clocks for system functions such as + * the USB clock, main system clock, or the clock output pin. + * @{ + */ + +/** + * Clock source selections for only the main A system clock. The main A system + * clock is used as an input into the main B system clock selector. Main clock A + * only needs to be setup if the main clock A input is used in the main clock + * system selector. + */ +typedef enum CHIP_SYSCTL_MAIN_A_CLKSRC { + SYSCTL_MAIN_A_CLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCTL_MAIN_A_CLKSRCA_MAINOSC, /*!< Crystal (main) oscillator in */ + SYSCTL_MAIN_A_CLKSRCA_SYSOSC = SYSCTL_MAIN_A_CLKSRCA_MAINOSC, + SYSCTL_MAIN_A_CLKSRCA_WDTOSC, /*!< Watchdog oscillator rate */ + SYSCTL_MAIN_A_CLKSRCA_RESERVED, +} CHIP_SYSCTL_MAIN_A_CLKSRC_T; + +/** + * @brief Set main A system clock source + * @param src : Clock source for main A + * @return Nothing + * @note This function only neesd to be setup if main clock A will be + * selected in the Chip_Clock_GetMain_B_ClockRate() function. + */ +STATIC INLINE void Chip_Clock_SetMain_A_ClockSource(CHIP_SYSCTL_MAIN_A_CLKSRC_T src) +{ + LPC_SYSCTL->MAINCLKSELA = (uint32_t) src; +} + +/** + * @brief Returns the main A clock source + * @return Returns which clock is used for the main A + */ +STATIC INLINE CHIP_SYSCTL_MAIN_A_CLKSRC_T Chip_Clock_GetMain_A_ClockSource(void) +{ + return (CHIP_SYSCTL_MAIN_A_CLKSRC_T) (LPC_SYSCTL->MAINCLKSELA); +} + +/** + * @brief Return main A clock rate + * @return main A clock rate in Hz + */ +uint32_t Chip_Clock_GetMain_A_ClockRate(void); + +/** + * Clock sources for only main B system clock + */ +typedef enum CHIP_SYSCTL_MAIN_B_CLKSRC { + SYSCTL_MAIN_B_CLKSRC_MAINCLKSELA = 0, /*!< main clock A */ + SYSCTL_MAIN_B_CLKSRC_SYSPLLIN, /*!< System PLL input */ + SYSCTL_MAIN_B_CLKSRC_SYSPLLOUT, /*!< System PLL output */ + SYSCTL_MAIN_B_CLKSRC_RTC, /*!< RTC oscillator 32KHz output */ +} CHIP_SYSCTL_MAIN_B_CLKSRC_T; + +/** + * @brief Set main B system clock source + * @param src : Clock source for main B + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetMain_B_ClockSource(CHIP_SYSCTL_MAIN_B_CLKSRC_T src) +{ + LPC_SYSCTL->MAINCLKSELB = (uint32_t) src; +} + +/** + * @brief Returns the main B clock source + * @return Returns which clock is used for the main B + */ +STATIC INLINE CHIP_SYSCTL_MAIN_B_CLKSRC_T Chip_Clock_GetMain_B_ClockSource(void) +{ + return (CHIP_SYSCTL_MAIN_B_CLKSRC_T) (LPC_SYSCTL->MAINCLKSELB); +} + +/** + * @brief Return main B clock rate + * @return main B clock rate + */ +uint32_t Chip_Clock_GetMain_B_ClockRate(void); + +/** + * Clock sources for main system clock. This is a mix of both main clock A + * and B seelctions. + */ +typedef enum CHIP_SYSCTL_MAINCLKSRC { + SYSCTL_MAINCLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCTL_MAINCLKSRCA_MAINOSC, /*!< Crystal (main) oscillator in */ + SYSCTL_MAINCLKSRCA_SYSOSC = SYSCTL_MAINCLKSRCA_MAINOSC, + SYSCTL_MAINCLKSRCA_WDTOSC, /*!< Watchdog oscillator rate */ + SYSCTL_MAINCLKSRC_SYSPLLIN = 5, /*!< System PLL input */ + SYSCTL_MAINCLKSRC_SYSPLLOUT, /*!< System PLL output */ + SYSCTL_MAINCLKSRC_RTC, /*!< RTC oscillator 32KHz output */ +} CHIP_SYSCTL_MAINCLKSRC_T; + +/** + * @brief Set main system clock source + * @param src : Main clock source + * @return Nothing + * @note This functions handles setup of both A and B main clock sources. + */ +void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src); + +/** + * @brief Returns the main clock source + * @return Returns which clock is used for the main clock source + * @note This functions handles both A and B main clock sources. + */ +CHIP_SYSCTL_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void); + +/** + * @brief Return main clock rate + * @return main clock rate + */ +uint32_t Chip_Clock_GetMainClockRate(void); + +/** + * @brief Return system clock rate + * @return system clock rate + */ +uint32_t Chip_Clock_GetSystemClockRate(void); + +/** + * Clock sources for USB (usb_clk) + */ +typedef enum CHIP_SYSCTL_USBCLKSRC { + SYSCTL_USBCLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCTL_USBCLKSRC_MAINOSC, /*!< Crystal (main) oscillator in */ + SYSCTL_USBCLKSRC_SYSOSC = SYSCTL_USBCLKSRC_MAINOSC, + SYSCTL_USBCLKSRC_PLLOUT, /*!< USB PLL out */ + SYSCTL_USBCLKSRC_MAINSYSCLK, /*!< Main system clock (B) */ +} CHIP_SYSCTL_USBCLKSRC_T; + +/** + * @brief Set USB clock source and divider + * @param src : Clock source for USB + * @param div : divider for USB clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The USB clock + * rate is either the main system clock or USB PLL output clock divided + * by this value. This function will also toggle the clock source + * update register to update the clock source. + */ +STATIC INLINE void Chip_Clock_SetUSBClockSource(CHIP_SYSCTL_USBCLKSRC_T src, uint32_t div) +{ + LPC_SYSCTL->USBCLKSEL = (uint32_t) src; + LPC_SYSCTL->USBCLKDIV = div; +} + +/** + * Clock sources for ADC asynchronous clock source select + */ +typedef enum CHIP_SYSCTL_ADCASYNCCLKSRC { + SYSCTL_ADCASYNCCLKSRC_IRC = 0, /*!< Internal oscillator */ + SYSCTL_ADCASYNCCLKSRC_SYSPLLOUT, /*!< System PLL out */ + SYSCTL_ADCASYNCCLKSRC_USBPLLOUT, /*!< USB PLL out */ + SYSCTL_ADCASYNCCLKSRC_SCTPLLOUT /*!< SCT PLL out */ +} CHIP_SYSCTL_ADCASYNCCLKSRC_T; + +/** + * @brief Set the ADC asynchronous clock source + * @param src : ADC asynchronous clock source + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetADCASYNCSource(CHIP_SYSCTL_ADCASYNCCLKSRC_T src) +{ + LPC_SYSCTL->ADCASYNCCLKSEL = (uint32_t) src; +} + +/** + * @brief Returns the ADC asynchronous clock source + * @return Returns which clock is used for the ADC asynchronous clock source + */ +STATIC INLINE CHIP_SYSCTL_ADCASYNCCLKSRC_T Chip_Clock_GetADCASYNCSource(void) +{ + return (CHIP_SYSCTL_ADCASYNCCLKSRC_T) (LPC_SYSCTL->ADCASYNCCLKSEL); +} + +/** + * @brief Return ADC asynchronous clock rate + * @return ADC asynchronous clock rate (not including divider) + */ +uint32_t Chip_Clock_GetADCASYNCRate(void); + +/** + * Clock sources for CLKOUT + */ +typedef enum CHIP_SYSCTL_CLKOUTSRC { + SYSCTL_CLKOUTSRC_IRC = 0, /*!< Internal oscillator for CLKOUT */ + SYSCTL_CLKOUTSRC_MAINOSC, /*!< Main oscillator for CLKOUT */ + SYSCTL_CLKOUTSRC_SYSOSC = SYSCTL_CLKOUTSRC_MAINOSC, + SYSCTL_CLKOUTSRC_WDTOSC, /*!< Watchdog oscillator for CLKOUT */ + SYSCTL_CLKOUTSRC_MAINSYSCLK, /*!< Main (B) system clock for CLKOUT */ + SYSCTL_CLKOUTSRC_USBPLLOUT = 5, /*!< USB PLL out */ + SYSCTL_CLKOUTSRC_SCTPLLOUT, /*!< SCT PLL out */ + SYSCTL_CLKOUTSRC_RTC32K /*!< RTC 32 kHz output */ +} CHIP_SYSCTL_CLKOUTSRC_T; + +/** + * @brief Set CLKOUT clock source and divider + * @param src : Clock source for CLKOUT + * @param div : divider for CLKOUT clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The CLKOUT clock + * rate is the clock source divided by the divider. This function will + * also toggle the clock source update register to update the clock + * source. + */ +void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div); + +/** + * @} + */ + +/** @defgroup CLOCK_15XX_CHIP_PLL: PLL setup functions + * @{ + */ + +/** + * Clock sources for system, USB, and SCT PLLs + */ +typedef enum CHIP_SYSCTL_PLLCLKSRC { + SYSCTL_PLLCLKSRC_IRC = 0, /*!< Internal oscillator in (may not work for USB) */ + SYSCTL_PLLCLKSRC_MAINOSC, /*!< Crystal (main) oscillator in */ + SYSCTL_PLLCLKSRC_SYSOSC = SYSCTL_PLLCLKSRC_MAINOSC, + SYSCTL_PLLCLKSRC_RESERVED1, /*!< Reserved */ + SYSCTL_PLLCLKSRC_RESERVED2, /*!< Reserved */ +} CHIP_SYSCTL_PLLCLKSRC_T; + +/** + * @brief Set System PLL clock source + * @param src : Clock source for system PLL + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src) +{ + LPC_SYSCTL->SYSPLLCLKSEL = (uint32_t) src; +} + +/** + * @brief Set System PLL divider values + * @param msel : PLL feedback divider value. M = msel + 1. + * @param psel : PLL post divider value. P = (1<SYSPLLCTRL = (msel & 0x3F) | ((psel & 0x3) << 6); +} + +/** + * @brief Read System PLL lock status + * @return true of the PLL is locked. false if not locked + */ +STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void) +{ + return (bool) ((LPC_SYSCTL->SYSPLLSTAT & 1) != 0); +} + +/** + * @brief Return System PLL input clock rate + * @return System PLL input clock rate + */ +uint32_t Chip_Clock_GetSystemPLLInClockRate(void); + +/** + * @brief Return System PLL output clock rate + * @return System PLL output clock rate + */ +uint32_t Chip_Clock_GetSystemPLLOutClockRate(void); + +/** + * @brief Set USB PLL clock source + * @param src : Clock source for USB PLL + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetUSBPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src) +{ + LPC_SYSCTL->USBPLLCLKSEL = (uint32_t) src; +} + +/** + * @brief Set USB PLL divider values + * @param msel : PLL feedback divider value. M = msel + 1. + * @param psel : PLL post divider value. P = (1<USBPLLCTRL = (msel & 0x3F) | ((psel & 0x3) << 6); +} + +/** + * @brief Read USB PLL lock status + * @return true of the PLL is locked. false if not locked + */ +STATIC INLINE bool Chip_Clock_IsUSBPLLLocked(void) +{ + return (bool) ((LPC_SYSCTL->USBPLLSTAT & 1) != 0); +} + +/** + * @brief Return USB PLL input clock rate + * @return USB PLL input clock rate + */ +uint32_t Chip_Clock_GetUSBPLLInClockRate(void); + +/** + * @brief Return USB PLL output clock rate + * @return USB PLL output clock rate + */ +uint32_t Chip_Clock_GetUSBPLLOutClockRate(void); + +/** + * @brief Set SCT PLL clock source + * @param src : Clock source for SCT PLL + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetSCTPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src) +{ + LPC_SYSCTL->SCTPLLCLKSEL = (uint32_t) src; +} + +/** + * @brief Set SCT PLL divider values + * @param msel : PLL feedback divider value. M = msel + 1. + * @param psel : PLL post divider value. P = (1<SCTPLLCTRL = (msel & 0x3F) | ((psel & 0x3) << 6); +} + +/** + * @brief Read SCT PLL lock status + * @return true of the PLL is locked. false if not locked + */ +STATIC INLINE bool Chip_Clock_IsSCTPLLLocked(void) +{ + return (bool) ((LPC_SYSCTL->SCTPLLSTAT & 1) != 0); +} + +/** + * @brief Return SCT PLL input clock rate + * @return SCT PLL input clock rate + */ +uint32_t Chip_Clock_GetSCTPLLInClockRate(void); + +/** + * @brief Return SCT PLL output clock rate + * @return SCT PLL output clock rate + */ +uint32_t Chip_Clock_GetSCTPLLOutClockRate(void); + +/** + * @} + */ + +/** @defgroup CLOCK_15XX_CHIP_SUP: Clock support functions + * Functions in this group include oscillator control and rates, peripheral + * clock control, and peripheral dividers. + * @{ + */ + +/** + * @brief Set system clock divider + * @param div : divider for system clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The system clock + * rate is the main system clock divided by this value. + */ +STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div) +{ + LPC_SYSCTL->SYSAHBCLKDIV = div; +} + +/** + * System and peripheral clocks + */ +typedef enum CHIP_SYSCTL_CLOCK { + /* Peripheral clock enables for SYSAHBCLKCTRL0 */ + SYSCTL_CLOCK_SYS = 0, /*!< System clock */ + SYSCTL_CLOCK_ROM, /*!< ROM clock */ + SYSCTL_CLOCK_SRAM1 = 3, /*!< SRAM1 clock */ + SYSCTL_CLOCK_SRAM2, /*!< SRAM2 clock */ + SYSCTL_CLOCK_FLASH = 7, /*!< FLASH controller clock */ + SYSCTL_CLOCK_EEPROM = 9, /*!< EEPROM controller clock */ + SYSCTL_CLOCK_MUX = 11, /*!< Input mux clock */ + SYSCTL_CLOCK_SWM, /*!< Switch matrix clock */ + SYSCTL_CLOCK_IOCON, /*!< IOCON clock */ + SYSCTL_CLOCK_GPIO0, /*!< GPIO0 clock */ + SYSCTL_CLOCK_GPIO1, /*!< GPIO1 clock */ + SYSCTL_CLOCK_GPIO2, /*!< GPIO2 clock */ + SYSCTL_CLOCK_PININT = 18, /*!< PININT clock */ + SYSCTL_CLOCK_GINT, /*!< grouped pin interrupt block clock */ + SYSCTL_CLOCK_DMA, /*!< DMA clock */ + SYSCTL_CLOCK_CRC, /*!< CRC clock */ + SYSCTL_CLOCK_WDT, /*!< WDT clock */ + SYSCTL_CLOCK_RTC, /*!< RTC clock */ + SYSCTL_CLOCK_ADC0 = 27, /*!< ADC0 clock */ + SYSCTL_CLOCK_ADC1, /*!< ADC1 clock */ + SYSCTL_CLOCK_DAC, /*!< DAC clock */ + SYSCTL_CLOCK_ACMP, /*!< ACMP clock */ + /* Peripheral clock enables for SYSAHBCLKCTRL1 */ + SYSCTL_CLOCK_MRT = 32, /*!< multi-rate timer clock */ + SYSCTL_CLOCK_RIT, /*!< repetitive interrupt timer clock */ + SYSCTL_CLOCK_SCT0, /*!< SCT0 clock */ + SYSCTL_CLOCK_SCT1, /*!< SCT1 clock */ + SYSCTL_CLOCK_SCT2, /*!< SCT2 clock */ + SYSCTL_CLOCK_SCT3, /*!< SCT3 clock */ + SYSCTL_CLOCK_SCTIPU, /*!< SCTIPU clock */ + SYSCTL_CLOCK_CAN, /*!< CAN clock */ + SYSCTL_CLOCK_SPI0 = 32 + 9, /*!< SPI0 clock */ + SYSCTL_CLOCK_SPI1, /*!< SPI1 clock */ + SYSCTL_CLOCK_I2C0 = 32 + 13, /*!< I2C0 clock */ + SYSCTL_CLOCK_UART0 = 32 + 17, /*!< UART0 clock */ + SYSCTL_CLOCK_UART1, /*!< UART1 clock */ + SYSCTL_CLOCK_UART2, /*!< UART2 clock */ + SYSCTL_CLOCK_QEI = 32 + 21, /*!< QEI clock */ + SYSCTL_CLOCK_USB = 32 + 23, /*!< USB clock */ +} CHIP_SYSCTL_CLOCK_T; + +/** + * @brief Enable a system or peripheral clock + * @param clk : Clock to enable + * @return Nothing + */ +void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk); + +/** + * @brief Disable a system or peripheral clock + * @param clk : Clock to disable + * @return Nothing + */ +void Chip_Clock_DisablePeriphClock(CHIP_SYSCTL_CLOCK_T clk); + +/** + * @brief Set system tick clock divider + * @param div : divider for system clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The system tick + * rate is the main system clock divided by this value. Use caution when using + * the CMSIS SysTick_Config() functions as they typically use SystemCoreClock + * for setup. + */ +STATIC INLINE void Chip_Clock_SetSysTickClockDiv(uint32_t div) +{ + LPC_SYSCTL->SYSTICKCLKDIV = div; +} + +/** + * @brief Returns system tick clock divider + * @return system tick clock divider + */ +STATIC INLINE uint32_t Chip_Clock_GetSysTickClockDiv(void) +{ + return LPC_SYSCTL->SYSTICKCLKDIV; +} + +/** + * @brief Returns the system tick rate as used with the system tick divider + * @return the system tick rate + */ +uint32_t Chip_Clock_GetSysTickClockRate(void); + +/** + * @brief Set IOCON glitch filter clock divider value + * @param div : value for IOCON filter divider + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. + */ +STATIC INLINE void Chip_Clock_SetIOCONFiltClockDiv(uint32_t div) +{ + LPC_SYSCTL->IOCONCLKDIV = div; +} + +/** + * @brief Return IOCON glitch filter clock divider value + * @return IOCON glitch filter clock divider value + */ +STATIC INLINE uint32_t Chip_Clock_GetIOCONFiltClockDiv(void) +{ + return LPC_SYSCTL->IOCONCLKDIV; +} + +/** + * @brief Set Asynchronous ADC clock divider value + * @param div : value for UART fractional generator multiplier value + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. + */ +STATIC INLINE void Chip_Clock_SetADCASYNCClockDiv(uint32_t div) +{ + LPC_SYSCTL->ADCASYNCCLKDIV = div; +} + +/** + * @brief Return Asynchronous ADC clock divider value + * @return Asynchronous ADC clock divider value + */ +STATIC INLINE uint32_t Chip_Clock_GetADCASYNCClockDiv(void) +{ + return LPC_SYSCTL->ADCASYNCCLKDIV; +} + +/** + * @brief Set UART base rate base rate (up to main clock rate) (all UARTs) + * @param rate : Desired rate for fractional divider/multipler output + * @param fEnable : true to use fractional clocking, false for integer clocking + * @return Actual rate generated + * @note All UARTs use the same base clock for their baud rate + * basis. This function is used to generate that clock, while the + * UART driver's SetBaud functions will attempt to get the closest + * baud rate from this base clock without altering it. This needs + * to be setup prior to individual UART setup.
+ * UARTs need a base clock 16x faster than the baud rate, so if you + * need a 115.2Kbps baud rate, you will need a clock rate of at + * least (115.2K * 16). The UART base clock is generated from the + * main system clock, so fractional clocking may be the only + * possible choice when using a low main system clock frequency. + * Do not alter the FRGCTRL or UARTCLKDIV registers after this call. + */ +uint32_t Chip_Clock_SetUARTBaseClockRate(uint32_t rate, bool fEnable); + +/** + * @brief Get UART base rate (all UARTs) + * @return UART base rate in Hz + */ +uint32_t Chip_Clock_GetUARTBaseClockRate(void); + +/** + * @brief Set The UART Fractional Generator Divider (all UARTs) + * @param div : Fractional Generator Divider value, should be 0xFF + * @return Nothing + */ +STATIC INLINE void Chip_Clock_SetUARTFRGDivider(uint8_t div) +{ + LPC_SYSCTL->UARTCLKDIV = (uint32_t) div; +} + +/** + * @brief Get The UART Fractional Generator Divider (all UARTs) + * @return Value of UART Fractional Generator Divider + */ +STATIC INLINE uint32_t Chip_Clock_GetUARTFRGDivider(void) +{ + return LPC_SYSCTL->UARTCLKDIV; +} + +/** + * @brief Enable the RTC 32KHz output + * @return Nothing + * @note This clock can be used for the main clock directly, but + * do not use this clock with the system PLL. + */ +STATIC INLINE void Chip_Clock_EnableRTCOsc(void) +{ + LPC_SYSCTL->RTCOSCCTRL = 1; +} + +/** + * @brief Disable the RTC 32KHz output + * @return Nothing + */ +STATIC INLINE void Chip_Clock_DisableRTCOsc(void) +{ + LPC_SYSCTL->RTCOSCCTRL = 0; +} + +/** + * @brief Returns the main oscillator clock rate + * @return main oscillator clock rate in Hz + */ +STATIC INLINE uint32_t Chip_Clock_GetMainOscRate(void) +{ + return OscRateIn; +} + +/** + * @brief Returns the internal oscillator (IRC) clock rate + * @return internal oscillator (IRC) clock rate in Hz + */ +STATIC INLINE uint32_t Chip_Clock_GetIntOscRate(void) +{ + return SYSCTL_IRC_FREQ; +} + +/** + * @brief Returns the RTC clock rate + * @return RTC oscillator clock rate in Hz + */ +STATIC INLINE uint32_t Chip_Clock_GetRTCOscRate(void) +{ + return RTCOscRateIn; +} + +/** + * @brief Return estimated watchdog oscillator rate + * @return Estimated watchdog oscillator rate + * @note This rate is accurate to plus or minus 40%. + */ +STATIC INLINE uint32_t Chip_Clock_GetWDTOSCRate(void) +{ + return SYSCTL_WDTOSC_FREQ; +} + +/** + * @} + */ + +/** @defgroup CLOCK_15XX_CHIP_MISC: Misc clock functions + * @{ + */ + +/** + * @brief Bypass System Oscillator and set oscillator frequency range + * @param bypass : Flag to bypass oscillator + * @param highfr : Flag to set oscillator range from 15-25 MHz + * @return Nothing + * @note Sets the PLL input to bypass the oscillator. This would be + * used if an external clock that is not an oscillator is attached + * to the XTALIN pin. + */ +void Chip_Clock_SetPLLBypass(bool bypass, bool highfr); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CLOCK_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/cmsis.h b/lpc_chip_15xx/inc/cmsis.h new file mode 100644 index 0000000..691ff19 --- /dev/null +++ b/lpc_chip_15xx/inc/cmsis.h @@ -0,0 +1,185 @@ +/* + * @brief Basic CMSIS include file for LPC15xx + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __CMSIS_15XX_H_ +#define __CMSIS_15XX_H_ + +#include "lpc_types.h" +#include "sys_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CMSIS_LPC15XX CHIP: LPC15xx CMSIS include file + * @ingroup CHIP_15XX_CMSIS_Drivers + * @{ + */ + +#if defined(__ARMCC_VERSION) +// Kill warning "#pragma push with no matching #pragma pop" + #pragma diag_suppress 2525 + #pragma push + #pragma anon_unions +#elif defined(__CWCC__) + #pragma push + #pragma cpp_extensions on +#elif defined(__GNUC__) +/* anonymous unions are enabled by default */ +#elif defined(__IAR_SYSTEMS_ICC__) +// #pragma push // FIXME not usable for IAR + #pragma language=extended +#else + #error Not supported compiler type +#endif + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +#if !defined(CHIP_LPC15XX) +#error Incorrect or missing device variant (CHIP_LPC15XX) +#endif + +/** @defgroup CMSIS_15XX_IRQ CHIP: LPC15xx peripheral interrupt numbers + * @{ + */ + +typedef enum IRQn { + Reset_IRQn = -15, /*!< Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< Memory Management, MPU mismatch, including Access Violation and No Match */ + BusFault_IRQn = -11, /*!< Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */ + UsageFault_IRQn = -10, /*!< Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /*!< System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< Debug Monitor */ + PendSV_IRQn = -2, /*!< Pendable request for system service */ + SysTick_IRQn = -1, /*!< System Tick Timer */ + + WDT_IRQn = 0, /*!< Watchdog timer Interrupt */ + WWDT_IRQn = WDT_IRQn, /*!< Watchdog timer Interrupt alias for WDT_IRQn */ + BOD_IRQn = 1, /*!< Brown Out Detect(BOD) Interrupt */ + FMC_IRQn = 2, /*!< FLASH Interrupt */ + FLASHEEPROM_IRQn = 3, /*!< EEPROM controller interrupt */ + DMA_IRQn = 4, /*!< DMA Interrupt */ + GINT0_IRQn = 5, /*!< GPIO group 0 Interrupt */ + GINT1_IRQn = 6, /*!< GPIO group 1 Interrupt */ + PIN_INT0_IRQn = 7, /*!< Pin Interrupt 0 */ + PIN_INT1_IRQn = 8, /*!< Pin Interrupt 1 */ + PIN_INT2_IRQn = 9, /*!< Pin Interrupt 2 */ + PIN_INT3_IRQn = 10, /*!< Pin Interrupt 3 */ + PIN_INT4_IRQn = 11, /*!< Pin Interrupt 4 */ + PIN_INT5_IRQn = 12, /*!< Pin Interrupt 5 */ + PIN_INT6_IRQn = 13, /*!< Pin Interrupt 6 */ + PIN_INT7_IRQn = 14, /*!< Pin Interrupt 7 */ + RITIMER_IRQn = 15, /*!< RITIMER interrupt */ + SCT0_IRQn = 16, /*!< SCT0 interrupt */ + SCT_IRQn = SCT0_IRQn, /*!< Optional alias for SCT0_IRQn */ + SCT1_IRQn = 17, /*!< SCT1 interrupt */ + SCT2_IRQn = 18, /*!< SCT2 interrupt */ + SCT3_IRQn = 19, /*!< SCT3 interrupt */ + MRT_IRQn = 20, /*!< MRT interrupt */ + UART0_IRQn = 21, /*!< UART0 Interrupt */ + UART1_IRQn = 22, /*!< UART1 Interrupt */ + UART2_IRQn = 23, /*!< UART2 Interrupt */ + I2C0_IRQn = 24, /*!< I2C0 Interrupt */ + I2C_IRQn = I2C0_IRQn, /*!< Optional alias for I2C0_IRQn */ + SPI0_IRQn = 25, /*!< SPI0 Interrupt */ + SPI1_IRQn = 26, /*!< SPI1 Interrupt */ + CAN_IRQn = 27, /*!< CAN Interrupt */ + USB0_IRQn = 28, /*!< USB IRQ interrupt */ + USB_IRQn = USB0_IRQn, /*!< Optional alias for USB0_IRQn */ + USB0_FIQ_IRQn = 29, /*!< USB FIQ interrupt */ + USB_FIQ_IRQn = USB0_FIQ_IRQn, /*!< Optional alias for USB0_FIQ_IRQn */ + USB_WAKEUP_IRQn = 30, /*!< USB wake-up interrupt Interrupt */ + ADC0_SEQA_IRQn = 31, /*!< ADC0_A sequencer Interrupt */ + ADC0_A_IRQn = ADC0_SEQA_IRQn, /*!< Optional alias for ADC0_SEQA_IRQn */ + ADC_A_IRQn = ADC0_SEQA_IRQn, /*!< Optional alias for ADC0_SEQA_IRQn */ + ADC0_SEQB_IRQn = 32, /*!< ADC0_B sequencer Interrupt */ + ADC0_B_IRQn = ADC0_SEQB_IRQn, /*!< Optional alias for ADC0_SEQB_IRQn */ + ADC_B_IRQn = ADC0_SEQB_IRQn, /*!< Optional alias for ADC0_SEQB_IRQn */ + ADC0_THCMP = 33, /*!< ADC0 threshold compare interrupt */ + ADC0_OVR = 34, /*!< ADC0 overrun interrupt */ + ADC1_SEQA_IRQn = 35, /*!< ADC1_A sequencer Interrupt */ + ADC1_A_IRQn = ADC1_SEQA_IRQn, /*!< Optional alias for ADC1_SEQA_IRQn */ + ADC1_SEQB_IRQn = 36, /*!< ADC1_B sequencer Interrupt */ + ADC1_B_IRQn = ADC1_SEQB_IRQn, /*!< Optional alias for ADC1_SEQB_IRQn */ + ADC1_THCMP = 37, /*!< ADC1 threshold compare interrupt */ + ADC1_OVR = 38, /*!< ADC1 overrun interrupt */ + DAC_IRQ = 39, /*!< DAC interrupt */ + CMP0_IRQ = 40, /*!< Analog comparator 0 interrupt */ + CMP_IRQn = CMP0_IRQ, /*!< Optional alias for CMP0_IRQ */ + CMP1_IRQ = 41, /*!< Analog comparator 1 interrupt */ + CMP2_IRQ = 42, /*!< Analog comparator 2 interrupt */ + CMP3_IRQ = 43, /*!< Analog comparator 3 interrupt */ + QEI_IRQn = 44, /*!< QEI interrupt */ + RTC_ALARM_IRQn = 45, /*!< RTC alarm interrupt */ + RTC_WAKE_IRQn = 46, /*!< RTC wake-up interrupt */ +} IRQn_Type; + +/** + * @} + */ + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/** @defgroup CMSIS_15XX_COMMON CHIP: LPC15xx Cortex CMSIS definitions + * @{ + */ + +#define __CM3_REV 0x0201 /*!< Cortex-M3 Core Revision */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 0 /*!< FPU present or not */ + +/** + * @} + */ + +#include "core_cm3.h" /*!< Cortex-M3 processor and core peripherals */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/core_cm3.h b/lpc_chip_15xx/inc/core_cm3.h new file mode 100644 index 0000000..0e215fc --- /dev/null +++ b/lpc_chip_15xx/inc/core_cm3.h @@ -0,0 +1,1627 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/lpc_chip_15xx/inc/core_cmFunc.h b/lpc_chip_15xx/inc/core_cmFunc.h new file mode 100644 index 0000000..139bc3c --- /dev/null +++ b/lpc_chip_15xx/inc/core_cmFunc.h @@ -0,0 +1,636 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/lpc_chip_15xx/inc/core_cmInstr.h b/lpc_chip_15xx/inc/core_cmInstr.h new file mode 100644 index 0000000..8946c2c --- /dev/null +++ b/lpc_chip_15xx/inc/core_cmInstr.h @@ -0,0 +1,688 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.20 + * @date 05. March 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/lpc_chip_15xx/inc/crc_15xx.h b/lpc_chip_15xx/inc/crc_15xx.h new file mode 100644 index 0000000..7d0f216 --- /dev/null +++ b/lpc_chip_15xx/inc/crc_15xx.h @@ -0,0 +1,262 @@ +/* + * @brief LPC15xx Cyclic Redundancy Check (CRC) Engine driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __CRC_15XX_H_ +#define __CRC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CRC_15XX CHIP: LPC15xx Cyclic Redundancy Check Engine driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief CRC register block structure + */ +typedef struct { /*!< CRC Structure */ + __IO uint32_t MODE; /*!< CRC Mode Register */ + __IO uint32_t SEED; /*!< CRC SEED Register */ + union { + __I uint32_t SUM; /*!< CRC Checksum Register. */ + __O uint32_t WRDATA32; /*!< CRC Data Register: write size 32-bit*/ + __O uint16_t WRDATA16; /*!< CRC Data Register: write size 16-bit*/ + __O uint8_t WRDATA8; /*!< CRC Data Register: write size 8-bit*/ + }; + +} LPC_CRC_T; + +/* + * @brief CRC MODE register description + */ +#define CRC_MODE_POLY_BITMASK ((0x03)) /** CRC polynomial Bit mask */ +#define CRC_MODE_POLY_CCITT (0x00) /** Select CRC-CCITT polynomial */ +#define CRC_MODE_POLY_CRC16 (0x01) /** Select CRC-16 polynomial */ +#define CRC_MODE_POLY_CRC32 (0x02) /** Select CRC-32 polynomial */ +#define CRC_MODE_WRDATA_BITMASK (0x03 << 2) /** CRC WR_Data Config Bit mask */ +#define CRC_MODE_WRDATA_BIT_RVS (1 << 2) /** Select Bit order reverse for WR_DATA (per byte) */ +#define CRC_MODE_WRDATA_CMPL (1 << 3) /** Select One's complement for WR_DATA */ +#define CRC_MODE_SUM_BITMASK (0x03 << 4) /** CRC Sum Config Bit mask */ +#define CRC_MODE_SUM_BIT_RVS (1 << 4) /** Select Bit order reverse for CRC_SUM */ +#define CRC_MODE_SUM_CMPL (1 << 5) /** Select One's complement for CRC_SUM */ + +#define MODE_CFG_CCITT (0x00) /** Pre-defined mode word for default CCITT setup */ +#define MODE_CFG_CRC16 (0x15) /** Pre-defined mode word for default CRC16 setup */ +#define MODE_CFG_CRC32 (0x36) /** Pre-defined mode word for default CRC32 setup */ + +#define CRC_SEED_CCITT (0x0000FFFF)/** Initial seed value for CCITT mode */ +#define CRC_SEED_CRC16 (0x00000000)/** Initial seed value for CRC16 mode */ +#define CRC_SEED_CRC32 (0xFFFFFFFF)/** Initial seed value for CRC32 mode */ + +/** + * @brief CRC polynomial + */ +typedef enum IP_CRC_001_POLY { + CRC_POLY_CCITT = CRC_MODE_POLY_CCITT, /**< CRC-CCIT polynomial */ + CRC_POLY_CRC16 = CRC_MODE_POLY_CRC16, /**< CRC-16 polynomial */ + CRC_POLY_CRC32 = CRC_MODE_POLY_CRC32, /**< CRC-32 polynomial */ + CRC_POLY_LAST, +} CRC_POLY_T; + +/** + * @brief Initializes the CRC Engine + * @return Nothing + */ +void Chip_CRC_Init(void); + +/** + * @brief Deinitializes the CRC Engine + * @return Nothing + */ +void Chip_CRC_Deinit(void); + +/** + * @brief Set the polynomial used for the CRC calculation + * @param poly : The enumerated polynomial to be used + * @param flags : An Or'ed value of flags that setup the mode + * @return Nothing + * @note Flags for setting up the mode word include CRC_MODE_WRDATA_BIT_RVS, + * CRC_MODE_WRDATA_CMPL, CRC_MODE_SUM_BIT_RVS, and CRC_MODE_SUM_CMPL. + */ +STATIC INLINE void Chip_CRC_SetPoly(CRC_POLY_T poly, uint32_t flags) +{ + LPC_CRC->MODE = (uint32_t) poly | flags; +} + +/** + * @brief Sets up the CRC engine for CRC16 mode + * @return Nothing + */ +STATIC INLINE void Chip_CRC_UseCRC16(void) +{ + LPC_CRC->MODE = MODE_CFG_CRC16; + LPC_CRC->SEED = CRC_SEED_CRC16; +} + +/** + * @brief Sets up the CRC engine for CRC32 mode + * @return Nothing + */ +STATIC INLINE void Chip_CRC_UseCRC32(void) +{ + LPC_CRC->MODE = MODE_CFG_CRC32; + LPC_CRC->SEED = CRC_SEED_CRC32; +} + +/** + * @brief Sets up the CRC engine for CCITT mode + * @return Nothing + */ +STATIC INLINE void Chip_CRC_UseCCITT(void) +{ + LPC_CRC->MODE = MODE_CFG_CCITT; + LPC_CRC->SEED = CRC_SEED_CCITT; +} + +/** + * @brief Engage the CRC engine with defaults based on the polynomial to be used + * @param poly : The enumerated polynomial to be used + * @return Nothing + */ +void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly); + +/** + * @brief Set the CRC Mode bits + * @param mode : Mode value + * @return Nothing + */ +STATIC INLINE void Chip_CRC_SetMode(uint32_t mode) +{ + LPC_CRC->MODE = mode; +} + +/** + * @brief Get the CRC Mode bits + * @return The current value of the CRC Mode bits + */ +STATIC INLINE uint32_t Chip_CRC_GetMode(void) +{ + return LPC_CRC->MODE; +} + +/** + * @brief Set the seed bits used by the CRC_SUM register + * @param seed : Seed value + * @return Nothing + */ +STATIC INLINE void Chip_CRC_SetSeed(uint32_t seed) +{ + LPC_CRC->SEED = seed; +} + +/** + * @brief Get the CRC seed value + * @return Seed value + */ +STATIC INLINE uint32_t Chip_CRC_GetSeed(void) +{ + return LPC_CRC->SEED; +} + +/** + * @brief Convenience function for writing 8-bit data to the CRC engine + * @param data : 8-bit data to write + * @return Nothing + */ +STATIC INLINE void Chip_CRC_Write8(uint8_t data) +{ + LPC_CRC->WRDATA8 = data; +} + +/** + * @brief Convenience function for writing 16-bit data to the CRC engine + * @param data : 16-bit data to write + * @return Nothing + */ +STATIC INLINE void Chip_CRC_Write16(uint16_t data) +{ + LPC_CRC->WRDATA16 = data; +} + +/** + * @brief Convenience function for writing 32-bit data to the CRC engine + * @param data : 32-bit data to write + * @return Nothing + */ +STATIC INLINE void Chip_CRC_Write32(uint32_t data) +{ + LPC_CRC->WRDATA32 = data; +} + +/** + * @brief Gets the CRC Sum based on the Mode and Seed as previously configured + * @return CRC Checksum value + */ +STATIC INLINE uint32_t Chip_CRC_Sum(void) +{ + return LPC_CRC->SUM; +} + +/** + * @brief Convenience function for computing a standard CCITT checksum from an 8-bit data block + * @param data : Pointer to the block of 8-bit data + * @param bytes : The number of bytes pointed to by data + * @return Check sum value + */ +uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes); + +/** + * @brief Convenience function for computing a standard CRC16 checksum from 16-bit data block + * @param data : Pointer to the block of 16-bit data + * @param hwords : The number of 16 byte entries pointed to by data + * @return Check sum value + */ +uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords); + +/** + * @brief Convenience function for computing a standard CRC32 checksum from 32-bit data block + * @param data : Pointer to the block of 32-bit data + * @param words : The number of 32-bit entries pointed to by data + * @return Check sum value + */ +uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/dac_15xx.h b/lpc_chip_15xx/inc/dac_15xx.h new file mode 100644 index 0000000..8a541fc --- /dev/null +++ b/lpc_chip_15xx/inc/dac_15xx.h @@ -0,0 +1,290 @@ +/* + * @brief LPC15xx D/A conversion driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __DAC_15XX_H_ +#define __DAC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup DAC_15XX CHIP: LPC15xx D/A conversion driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief DAC register block structure + */ +typedef struct { /*!< DAC Structure */ + __IO uint32_t VAL; /*!< DAC register. Holds the conversion data */ + __IO uint32_t CTRL; /*!< DAC control register */ + __IO uint32_t CNTVAL; /*!< DAC counter value register */ +} LPC_DAC_T; + +/** After this field is written with a + new VALUE, the voltage on the AOUT pin (with respect to VSSA) + is VALUE*((VREFP_DAC - VREFN)/4095) + VREFN */ +#define DAC_VALUE(n) ((uint32_t) ((n & 0x0FFF) << 4)) + +/* Bit Definitions for DAC Control register */ +#define DAC_INT_DMA_FLAG (1 << 0) +#define DAC_TRIG_SRC_MASK (0x7 << 1) +#define DAC_TRIG_SRC_BIT (1 << 1) +#define DAC_POLARITY (1 << 4) +#define DAC_SYNC_BYPASS (1 << 5) +#define DAC_TIM_ENA_BIT (1 << 6) +#define DAC_DBLBUF_ENA (1 << 7) +#define DAC_SHUTOFF_ENA (1 << 8) +#define DAC_SHUTOFF_FLAG (1 << 9) +#define DAC_DACCTRL_MASK ((uint32_t) 0xFF << 1) +#define DAC_CTRL_UNUSED ((uint32_t) 0x7FFFF << 13) + +/** Value to reload interrupt/DMA timer */ +#define DAC_CNT_VALUE(n) ((uint32_t) ((n) & 0xffff)) + +/** + * @brief Initial DAC configuration - Value to AOUT is 0 + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +void Chip_DAC_Init(LPC_DAC_T *pDAC); + +/** + * @brief Shutdown DAC + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +void Chip_DAC_DeInit(LPC_DAC_T *pDAC); + +/** + * @brief Update value to DAC buffer + * @param pDAC : pointer to LPC_DAC_T + * @param dac_value : 12 bit input value for conversion + * @return Nothing + */ +STATIC INLINE void Chip_DAC_UpdateValue(LPC_DAC_T *pDAC, uint32_t dac_value) +{ + pDAC->VAL = DAC_VALUE(dac_value); +} + +/** + * @brief Get status for interrupt/DMA time out + * @param pDAC : pointer to LPC_DAC_T + * @return TRUE if interrupt/DMA flag is set else returns FALSE + */ +STATIC INLINE bool Chip_DAC_GetIntStatus(LPC_DAC_T *pDAC) +{ + return (pDAC->CTRL & DAC_INT_DMA_FLAG) != 0; +} + +/** + * @brief Set Interrupt/DMA trigger source as Internal timer, enable timer before this call + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_SetTrgSrcInternal(LPC_DAC_T *pDAC) +{ + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_TRIG_SRC_BIT); +} + +/** + * @brief Set Interrupt/DMA trigger source as External Pin + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_SetTrgSrcExternal(LPC_DAC_T *pDAC) +{ + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_TRIG_SRC_BIT; +} + +/** + * @brief Set Polarity for external trigger pin + * @param pDAC : pointer to LPC_DAC_T + * @param falling_edge : If TRUE indicates that the trigger polarity is Falling edge + * else it is a Rising edge + * @return Nothing + */ +STATIC INLINE void Chip_DAC_SetExtTriggerPolarity(LPC_DAC_T *pDAC, bool falling_edge) +{ + if (falling_edge) { + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_POLARITY; + } + else { + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_POLARITY ); + } +} + +/** + * @brief Enable Sync Bypass, only if external trigger is in sync with SysClk + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_EnableSyncBypass(LPC_DAC_T *pDAC) +{ + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_SYNC_BYPASS; +} + +/** + * @brief Disable Sync Bypass + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_DisableSyncBypass(LPC_DAC_T *pDAC) +{ + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_SYNC_BYPASS); +} + +/** + * @brief Enable Internal Timer, CNTVAL should be loaded before enabling timer + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_EnableIntTimer(LPC_DAC_T *pDAC) +{ + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_TIM_ENA_BIT; +} + +/** + * @brief Disable Internal Timer + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_DisableIntTimer(LPC_DAC_T *pDAC) +{ + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_TIM_ENA_BIT); +} + +/** + * @brief Enable DAC Double Buffer + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_EnableDoubleBuffer(LPC_DAC_T *pDAC) +{ + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_DBLBUF_ENA; +} + +/** + * @brief Disable DAC Double Buffer + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_DisableDoubleBuffer(LPC_DAC_T *pDAC) +{ + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_DBLBUF_ENA); +} + +/** + * @brief Enable DAC Shut Off + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_EnableShutOff(LPC_DAC_T *pDAC) +{ + pDAC->CTRL = (pDAC->CTRL & ~DAC_CTRL_UNUSED) | DAC_SHUTOFF_ENA; +} + +/** + * @brief Disable DAC Shut Off + * @param pDAC : pointer to LPC_DAC_T + * @return Nothing + */ +STATIC INLINE void Chip_DAC_DisableShutOff(LPC_DAC_T *pDAC) +{ + pDAC->CTRL &= ~(DAC_CTRL_UNUSED | DAC_SHUTOFF_ENA); +} + +/** + * @brief Get status of DAC Shut Off + * @param pDAC : pointer to LPC_DAC_T + * @return TRUE if DAC is shut off else returns FALSE + */ +STATIC INLINE bool Chip_DAC_GetShutOffStatus(LPC_DAC_T *pDAC) +{ + return (pDAC->CTRL & DAC_SHUTOFF_FLAG) != 0; +} + +/** + * @brief Enables the DMA operation and controls DMA timer + * @param pDAC : pointer to LPC_DAC_T + * @param dacFlags : An Or'ed value of the following DAC values: + * - DAC_TRIG_SRC_BIT :set trigger source for Interrupt/DMA + * 0 - Internal timer trigger, 1 - External trigger + * - DAC_POLARITY :polarity of the trigger if it is external + * - DAC_SYNC_BYPASS :Synchronize selection is trigger is external + * - DAC_TIM_ENA_BIT :enable/disable internal timer + * - DAC_DBLBUF_ENA :enable/disable DAC double buffering feature + * - DAC_SHUTOFF_ENA :enable/disable DAC Shutoff Pin + * @return Nothing + * @note Pass an Or'ed value of the DAC flags to enable those options. + */ +STATIC INLINE void Chip_DAC_ConfigDMAConverterControl(LPC_DAC_T *pDAC, uint32_t dacFlags) +{ + uint32_t temp; + + temp = pDAC->CTRL & ~(DAC_CTRL_UNUSED | DAC_DACCTRL_MASK); + pDAC->CTRL = temp | dacFlags; +} + +/** + * @brief Set reload value for interrupt/DMA timer + * @param pDAC : pointer to LPC_DAC_T + * @param time_out : time out to reload for interrupt/DMA timer. + * time out rate will be SysClk/(time_out + 1) + * @return Nothing + */ +STATIC INLINE void Chip_DAC_SetDMATimeOut(LPC_DAC_T *pDAC, uint32_t time_out) +{ + pDAC->CNTVAL = DAC_CNT_VALUE(time_out); +} + +/** + * @brief Set reload value for interrupt/DMA timer to trigger periodic interrupts + * @param pDAC : pointer to LPC_DAC_T + * @param periodHz : Frequency of Timer interrupts in Hz + * @return Nothing + */ +STATIC INLINE void Chip_DAC_SetReqInterval(LPC_DAC_T *pDAC, uint32_t periodHz) +{ + uint32_t time_out = Chip_Clock_GetSystemClockRate() / periodHz - 1; + pDAC->CNTVAL = DAC_CNT_VALUE(time_out); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DAC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/dma_15xx.h b/lpc_chip_15xx/inc/dma_15xx.h new file mode 100644 index 0000000..231a1a9 --- /dev/null +++ b/lpc_chip_15xx/inc/dma_15xx.h @@ -0,0 +1,692 @@ +/* + * @brief LPC15xx DMA chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __DMA_15XX_H_ +#define __DMA_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup DMA_15XX CHIP: LPC15xx DMA Controller driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief DMA Controller shared registers structure + */ +typedef struct { /*!< DMA shared registers structure */ + __IO uint32_t ENABLESET; /*!< DMA Channel Enable read and Set for all DMA channels */ + __I uint32_t RESERVED0; + __O uint32_t ENABLECLR; /*!< DMA Channel Enable Clear for all DMA channels */ + __I uint32_t RESERVED1; + __I uint32_t ACTIVE; /*!< DMA Channel Active status for all DMA channels */ + __I uint32_t RESERVED2; + __I uint32_t BUSY; /*!< DMA Channel Busy status for all DMA channels */ + __I uint32_t RESERVED3; + __IO uint32_t ERRINT; /*!< DMA Error Interrupt status for all DMA channels */ + __I uint32_t RESERVED4; + __IO uint32_t INTENSET; /*!< DMA Interrupt Enable read and Set for all DMA channels */ + __I uint32_t RESERVED5; + __O uint32_t INTENCLR; /*!< DMA Interrupt Enable Clear for all DMA channels */ + __I uint32_t RESERVED6; + __IO uint32_t INTA; /*!< DMA Interrupt A status for all DMA channels */ + __I uint32_t RESERVED7; + __IO uint32_t INTB; /*!< DMA Interrupt B status for all DMA channels */ + __I uint32_t RESERVED8; + __O uint32_t SETVALID; /*!< DMA Set ValidPending control bits for all DMA channels */ + __I uint32_t RESERVED9; + __O uint32_t SETTRIG; /*!< DMA Set Trigger control bits for all DMA channels */ + __I uint32_t RESERVED10; + __O uint32_t ABORT; /*!< DMA Channel Abort control for all DMA channels */ +} LPC_DMA_COMMON_T; + +/** + * @brief DMA Controller shared registers structure + */ +typedef struct { /*!< DMA channel register structure */ + __IO uint32_t CFG; /*!< DMA Configuration register */ + __I uint32_t CTLSTAT; /*!< DMA Control and status register */ + __IO uint32_t XFERCFG; /*!< DMA Transfer configuration register */ + __I uint32_t RESERVED; +} LPC_DMA_CHANNEL_T; + +/* DMA channel mapping - each channel is mapped to an individual peripheral + and direction or a DMA imput mux trigger */ +typedef enum { + DMAREQ_USART0_RX = 0, /*!< USART0 receive DMA channel */ + DMA_CH0 = DMAREQ_USART0_RX, + DMAREQ_USART0_TX, /*!< USART0 transmit DMA channel */ + DMA_CH1 = DMAREQ_USART0_TX, + DMAREQ_USART1_RX, /*!< USART1 receive DMA channel */ + DMA_CH2 = DMAREQ_USART1_RX, + DMAREQ_USART1_TX, /*!< USART1 transmit DMA channel */ + DMA_CH3 = DMAREQ_USART1_TX, + DMAREQ_USART2_RX, /*!< USART2 receive DMA channel */ + DMA_CH4 = DMAREQ_USART2_RX, + DMAREQ_USART2_TX, /*!< USART2 transmit DMA channel */ + DMA_CH5 = DMAREQ_USART2_TX, + DMAREQ_SPI0_RX, /*!< SSP0 receive DMA channel */ + DMA_CH6 = DMAREQ_SPI0_RX, + DMAREQ_SPI0_TX, /*!< SSP0 transmit DMA channel */ + DMA_CH7 = DMAREQ_SPI0_TX, + DMAREQ_SPI1_RX, /*!< SSP1 receive DMA channel */ + DMA_CH8 = DMAREQ_SPI1_RX, + DMAREQ_SPI1_TX, /*!< SSP1 transmit DMA channel */ + DMA_CH9 = DMAREQ_SPI1_TX, + DMAREQ_I2C0_SLV, /*!< I2C0 slave DMA channel */ + DMA_CH10 = DMAREQ_I2C0_SLV, + DMAREQ_I2C0_MST, /*!< I2C0 master DMA channel */ + DMA_CH11 = DMAREQ_I2C0_MST, + DMAREQ_I2C0_MONITOR, /*!< I2C0 monitor DMA channel */ + DMA_CH12 = DMAREQ_I2C0_MONITOR, + DMAREQ_DAC_IRQ, /*!< DAC DMA channel */ + DMA_CH13 = DMAREQ_DAC_IRQ, + DMAREQ_RESERVED_14, + DMA_CH14 = DMAREQ_RESERVED_14, + DMAREQ_RESERVED_15, + DMA_CH15 = DMAREQ_RESERVED_15, + DMAREQ_RESERVED_16, + DMA_CH16 = DMAREQ_RESERVED_16, + DMAREQ_RESERVED_17, + DMA_CH17 = DMAREQ_RESERVED_17 +} DMA_CHID_T; + +/* On LPC15xx, Max DMA channel is 18 */ +#define MAX_DMA_CHANNEL (DMA_CH17 + 1) + +/** + * @brief DMA Controller register block structure + */ +typedef struct { /*!< DMA Structure */ + __IO uint32_t CTRL; /*!< DMA control register */ + __I uint32_t INTSTAT; /*!< DMA Interrupt status register */ + __IO uint32_t SRAMBASE; /*!< DMA SRAM address of the channel configuration table */ + __I uint32_t RESERVED2[5]; + LPC_DMA_COMMON_T DMACOMMON[1]; /*!< DMA shared channel (common) registers */ + __I uint32_t RESERVED0[225]; + LPC_DMA_CHANNEL_T DMACH[MAX_DMA_CHANNEL]; /*!< DMA channel registers */ +} LPC_DMA_T; + +/** @defgroup DMA_COMMONDRV_15XX CHIP: LPC15xx DMA Controller driver common functions + * @{ + */ + +/** + * @brief Initialize DMA controller + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + */ +STATIC INLINE void Chip_DMA_Init(LPC_DMA_T *pDMA) +{ + (void) pDMA; + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_DMA); + Chip_SYSCTL_PeriphReset(RESET_DMA); +} + +/** + * @brief De-Initialize DMA controller + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + */ +STATIC INLINE void Chip_DMA_DeInit(LPC_DMA_T *pDMA) +{ + (void) pDMA; + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_DMA); +} + +/** + * @brief Enable DMA controller + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + */ +STATIC INLINE void Chip_DMA_Enable(LPC_DMA_T *pDMA) +{ + pDMA->CTRL = 1; +} + +/** + * @brief Disable DMA controller + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + */ +STATIC INLINE void Chip_DMA_Disable(LPC_DMA_T *pDMA) +{ + pDMA->CTRL = 0; +} + +/* DMA interrupt status bits (common) */ +#define DMA_INTSTAT_ACTIVEINT 0x2 /*!< Summarizes whether any enabled interrupts are pending */ +#define DMA_INTSTAT_ACTIVEERRINT 0x4 /*!< Summarizes whether any error interrupts are pending */ + +/** + * @brief Get pending interrupt or error interrupts + * @param pDMA : The base of DMA controller on the chip + * @return An Or'ed value of DMA_INTSTAT_* types + * @note If any DMA channels have an active interrupt or error interrupt + * pending, this functional will a common status that applies to all + * channels. + */ +STATIC INLINE uint32_t Chip_DMA_GetIntStatus(LPC_DMA_T *pDMA) +{ + return pDMA->INTSTAT; +} + +/* DMA channel source/address/next descriptor */ +typedef struct { + uint32_t xfercfg; /*!< Transfer configuration (only used in linked lists and ping-pong configs) */ + uint32_t source; /*!< DMA transfer source end address */ + uint32_t dest; /*!< DMA transfer desintation end address */ + uint32_t next; /*!< Link to next DMA descriptor, must be 16 byte aligned */ +} DMA_CHDESC_T; + +/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase() + function if a DMA SRAM table is needed. */ +extern DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL]; + +/** + * @brief Set DMA controller SRAM base address + * @param pDMA : The base of DMA controller on the chip + * @param base : The base address where the DMA descriptors will be stored + * @return Nothing + * @note A 288 byte block of memory aligned on a 512 byte boundary must be + * provided for this function. It sets the base address used for + * DMA descriptor table (18 descriptors total that use 16 bytes each).
+ * + * A pre-defined table with correct alignment can be used for this + * function by calling Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table)); + */ +STATIC INLINE void Chip_DMA_SetSRAMBase(LPC_DMA_T *pDMA, uint32_t base) +{ + pDMA->SRAMBASE = base; +} + +/** + * @brief Returns DMA controller SRAM base address + * @param pDMA : The base of DMA controller on the chip + * @return The base address where the DMA descriptors are stored + */ +STATIC INLINE uint32_t Chip_DMA_GetSRAMBase(LPC_DMA_T *pDMA) +{ + return pDMA->SRAMBASE; +} + +/** + * @} + */ + +/** @defgroup DMA_COMMON_15XX CHIP: LPC15xx DMA Controller driver common channel functions + * @{ + */ + +/** + * @brief Enables a single DMA channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_EnableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].ENABLESET = (1 << ch); +} + +/** + * @brief Disables a single DMA channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_DisableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].ENABLECLR = (1 << ch); +} + +/** + * @brief Returns all enabled DMA channels + * @param pDMA : The base of DMA controller on the chip + * @return An Or'ed value of all enabled DMA channels (0 - 17) + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) is enabled. A low state is disabled. + */ +STATIC INLINE uint32_t Chip_DMA_GetEnabledChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].ENABLESET; +} + +/** + * @brief Returns all active DMA channels + * @param pDMA : The base of DMA controller on the chip + * @return An Or'ed value of all active DMA channels (0 - 17) + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) is active. A low state is inactive. A active + * channel indicates that a DMA operation has been started but + * not yet fully completed. + */ +STATIC INLINE uint32_t Chip_DMA_GetActiveChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].ACTIVE; +} + +/** + * @brief Returns all busy DMA channels + * @param pDMA : The base of DMA controller on the chip + * @return An Or'ed value of all busy DMA channels (0 - 17) + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) is busy. A low state is not busy. A DMA + * channel is considered busy when there is any operation + * related to that channel in the DMA controller�s internal + * pipeline. + */ +STATIC INLINE uint32_t Chip_DMA_GetBusyChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].BUSY; +} + +/** + * @brief Returns pending error interrupt status for all DMA channels + * @param pDMA : The base of DMA controller on the chip + * @return An Or'ed value of all channels (0 - 17) error interrupt status + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) has a pending error interrupt. A low state + * indicates no error interrupt. + */ +STATIC INLINE uint32_t Chip_DMA_GetErrorIntChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].ERRINT; +} + +/** + * @brief Clears a pending error interrupt status for a single DMA channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_ClearErrorIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].ERRINT = (1 << ch); +} + +/** + * @brief Enables a single DMA channel's interrupt used in common DMA interrupt + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_EnableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].INTENSET = (1 << ch); +} + +/** + * @brief Disables a single DMA channel's interrupt used in common DMA interrupt + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_DisableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].INTENCLR = (1 << ch); +} + +/** + * @brief Returns all enabled interrupt channels + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) has an enabled interrupt for the channel. + * A low state indicates that the DMA channel will not contribute + * to the common DMA interrupt status. + */ +STATIC INLINE uint32_t Chip_DMA_GetEnableIntChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].INTENSET; +} + +/** + * @brief Returns active A interrupt status for all channels + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) has an active A interrupt for the channel. + * A low state indicates that the A interrupt is not active. + */ +STATIC INLINE uint32_t Chip_DMA_GetActiveIntAChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].INTA; +} + +/** + * @brief Clears active A interrupt status for a single channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_ClearActiveIntAChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].INTA = (1 << ch); +} + +/** + * @brief Returns active B interrupt status for all channels + * @param pDMA : The base of DMA controller on the chip + * @return Nothing + * @note A high values in bits 0 .. 17 in the return values indicates + * that the channel for that bit (bit 0 = channel 0, bit 1 - + * channel 1, etc.) has an active B interrupt for the channel. + * A low state indicates that the B interrupt is not active. + */ +STATIC INLINE uint32_t Chip_DMA_GetActiveIntBChannels(LPC_DMA_T *pDMA) +{ + return pDMA->DMACOMMON[0].INTB; +} + +/** + * @brief Clears active B interrupt status for a single channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_ClearActiveIntBChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].INTB = (1 << ch); +} + +/** + * @brief Sets the VALIDPENDING control bit for a single channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + * @note See the User Manual for more information for what this bit does. + * + */ +STATIC INLINE void Chip_DMA_SetValidChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].SETVALID = (1 << ch); +} + +/** + * @brief Sets the TRIG bit for a single channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + * @note See the User Manual for more information for what this bit does. + */ +STATIC INLINE void Chip_DMA_SetTrigChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].SETTRIG = (1 << ch); +} + +/** + * @brief Aborts a DMA operation for a single channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + * @note To abort a channel, the channel should first be disabled. Then wait + * until the channel is no longer busy by checking the corresponding + * bit in BUSY. Finally, abort the channel operation. This prevents the + * channel from restarting an incomplete operation when it is enabled + * again. + */ +STATIC INLINE void Chip_DMA_AbortChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + pDMA->DMACOMMON[0].ABORT = (1 << ch); +} + +/** + * @} + */ + +/** @defgroup DMA_CHANNEL_15XX CHIP: LPC15xx DMA Controller driver channel specific functions + * @{ + */ + +/* Support macro for DMA_CHDESC_T */ +#define DMA_ADDR(addr) ((uint32_t) (addr)) + +/* Support definitions for setting the configuration of a DMA channel. You + will need to get more information on these options from the User manual. */ +#define DMA_CFG_PERIPHREQEN (1 << 0) /*!< Enables Peripheral DMA requests */ +#define DMA_CFG_HWTRIGEN (1 << 1) /*!< Use hardware triggering via imput mux */ +#define DMA_CFG_TRIGPOL_LOW (0 << 4) /*!< Hardware trigger is active low or falling edge */ +#define DMA_CFG_TRIGPOL_HIGH (1 << 4) /*!< Hardware trigger is active high or rising edge */ +#define DMA_CFG_TRIGTYPE_EDGE (0 << 5) /*!< Hardware trigger is edge triggered */ +#define DMA_CFG_TRIGTYPE_LEVEL (1 << 5) /*!< Hardware trigger is level triggered */ +#define DMA_CFG_TRIGBURST_SNGL (0 << 6) /*!< Single transfer. Hardware trigger causes a single transfer */ +#define DMA_CFG_TRIGBURST_BURST (1 << 6) /*!< Burst transfer (see UM) */ +#define DMA_CFG_BURSTPOWER_1 (0 << 8) /*!< Set DMA burst size to 1 transfer */ +#define DMA_CFG_BURSTPOWER_2 (1 << 8) /*!< Set DMA burst size to 2 transfers */ +#define DMA_CFG_BURSTPOWER_4 (2 << 8) /*!< Set DMA burst size to 4 transfers */ +#define DMA_CFG_BURSTPOWER_8 (3 << 8) /*!< Set DMA burst size to 8 transfers */ +#define DMA_CFG_BURSTPOWER_16 (4 << 8) /*!< Set DMA burst size to 16 transfers */ +#define DMA_CFG_BURSTPOWER_32 (5 << 8) /*!< Set DMA burst size to 32 transfers */ +#define DMA_CFG_BURSTPOWER_64 (6 << 8) /*!< Set DMA burst size to 64 transfers */ +#define DMA_CFG_BURSTPOWER_128 (7 << 8) /*!< Set DMA burst size to 128 transfers */ +#define DMA_CFG_BURSTPOWER_256 (8 << 8) /*!< Set DMA burst size to 256 transfers */ +#define DMA_CFG_BURSTPOWER_512 (9 << 8) /*!< Set DMA burst size to 512 transfers */ +#define DMA_CFG_BURSTPOWER_1024 (10 << 8) /*!< Set DMA burst size to 1024 transfers */ +#define DMA_CFG_BURSTPOWER(n) ((n) << 8) /*!< Set DMA burst size to 2^n transfers, max n=10 */ +#define DMA_CFG_SRCBURSTWRAP (1 << 14) /*!< Source burst wrapping is enabled for this DMA channel */ +#define DMA_CFG_DSTBURSTWRAP (1 << 15) /*!< Destination burst wrapping is enabled for this DMA channel */ +#define DMA_CFG_CHPRIORITY(p) ((p) << 16) /*!< Sets DMA channel priority, min 0 (highest), max 3 (lowest) */ + +/** + * @brief Setup a DMA channel configuration + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param cfg : An Or'ed value of DMA_CFG_* values that define the channel's configuration + * @return Nothing + * @note This function sets up all configurable options for the DMA channel. + * These options are usually set once for a channel and then unchanged.
+ * + * The following example show how to configure the channel for peripheral + * DMA requests, burst transfer size of 1 (in 'transfers', not bytes), + * continuous reading of the same source address, incrementing destination + * address, and highest channel priority.
+ * Example: Chip_DMA_SetupChannelConfig(pDMA, SSP0_RX_DMA, + * (DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_1 | + * DMA_CFG_SRCBURSTWRAP | DMA_CFG_CHPRIORITY(0)));
+ * + * The following example show how to configure the channel for an external + * trigger from the imput mux with low edge polarity, a burst transfer size of 8, + * incrementing source and destination addresses, and lowest channel + * priority.
+ * Example: Chip_DMA_SetupChannelConfig(pDMA, DMA_CH14, + * (DMA_CFG_HWTRIGEN | DMA_CFG_TRIGPOL_LOW | DMA_CFG_TRIGTYPE_EDGE | + * DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_8 | + * DMA_CFG_CHPRIORITY(3)));
+ * + * For non-peripheral DMA triggering (DMA_CFG_HWTRIGEN definition), use the + * DMA input mux functions to configure the DMA trigger source for a DMA channel. + */ +STATIC INLINE void Chip_DMA_SetupChannelConfig(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg) +{ + pDMA->DMACH[ch].CFG = cfg; +} + +/* DMA channel control and status register definitions */ +#define DMA_CTLSTAT_VALIDPENDING (1 << 0) /*!< Valid pending flag for this channel */ +#define DMA_CTLSTAT_TRIG (1 << 2) /*!< Trigger flag. Indicates that the trigger for this channel is currently set */ + +/** + * @brief Returns channel specific status flags + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return AN Or'ed value of DMA_CTLSTAT_VALIDPENDING and DMA_CTLSTAT_TRIG + */ +STATIC INLINE uint32_t Chip_DMA_GetChannelStatus(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + return pDMA->DMACH[ch].CTLSTAT; +} + +/* DMA channel transfer configuration registers definitions */ +#define DMA_XFERCFG_CFGVALID (1 << 0) /*!< Configuration Valid flag */ +#define DMA_XFERCFG_RELOAD (1 << 1) /*!< Indicates whether the channels control structure will be reloaded when the current descriptor is exhausted */ +#define DMA_XFERCFG_SWTRIG (1 << 2) /*!< Software Trigger */ +#define DMA_XFERCFG_CLRTRIG (1 << 3) /*!< Clear Trigger */ +#define DMA_XFERCFG_SETINTA (1 << 4) /*!< Set Interrupt flag A for this channel to fire when descriptor is complete */ +#define DMA_XFERCFG_SETINTB (1 << 5) /*!< Set Interrupt flag B for this channel to fire when descriptor is complete */ +#define DMA_XFERCFG_WIDTH_8 (0 << 8) /*!< 8-bit transfers are performed */ +#define DMA_XFERCFG_WIDTH_16 (1 << 8) /*!< 16-bit transfers are performed */ +#define DMA_XFERCFG_WIDTH_32 (2 << 8) /*!< 32-bit transfers are performed */ +#define DMA_XFERCFG_SRCINC_0 (0 << 12) /*!< DMA source address is not incremented after a transfer */ +#define DMA_XFERCFG_SRCINC_1 (1 << 12) /*!< DMA source address is incremented by 1 (width) after a transfer */ +#define DMA_XFERCFG_SRCINC_2 (2 << 12) /*!< DMA source address is incremented by 2 (width) after a transfer */ +#define DMA_XFERCFG_SRCINC_4 (3 << 12) /*!< DMA source address is incremented by 4 (width) after a transfer */ +#define DMA_XFERCFG_DSTINC_0 (0 << 14) /*!< DMA destination address is not incremented after a transfer */ +#define DMA_XFERCFG_DSTINC_1 (1 << 14) /*!< DMA destination address is incremented by 1 (width) after a transfer */ +#define DMA_XFERCFG_DSTINC_2 (2 << 14) /*!< DMA destination address is incremented by 2 (width) after a transfer */ +#define DMA_XFERCFG_DSTINC_4 (3 << 14) /*!< DMA destination address is incremented by 4 (width) after a transfer */ +#define DMA_XFERCFG_XFERCOUNT(n) ((n - 1) << 16) /*!< DMA transfer count in 'transfers', between (0)1 and (1023)1024 */ + +/** + * @brief Setup a DMA channel transfer configuration + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param cfg : An Or'ed value of DMA_XFERCFG_* values that define the channel's transfer configuration + * @return Nothing + * @note This function sets up the transfer configuration for the DMA channel.
+ * + * The following example show how to configure the channel's transfer for + * multiple transfer descriptors (ie, ping-pong), interrupt 'A' trigger on + * transfer descriptor completion, 128 byte size transfers, and source and + * destination address increment.
+ * Example: Chip_DMA_SetupChannelTransfer(pDMA, SSP0_RX_DMA, + * (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_RELOAD | DMA_XFERCFG_SETINTA | + * DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_1 | + * DMA_XFERCFG_XFERCOUNT(128)));
+ */ +STATIC INLINE void Chip_DMA_SetupChannelTransfer(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg) +{ + pDMA->DMACH[ch].XFERCFG = cfg; +} + +/** + * @brief Set DMA transfer register interrupt bits (safe) + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param mask : Bits to set + * @return Nothing + * @note This function safely sets bits in the DMA channel specific XFERCFG + * register. + */ +void Chip_DMA_SetTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask); + +/** + * @brief Clear DMA transfer register interrupt bits (safe) + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param mask : Bits to clear + * @return Nothing + * @note This function safely clears bits in the DMA channel specific XFERCFG + * register. + */ +void Chip_DMA_ClearTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask); + +/** + * @brief Update the transfer size in an existing DMA channel transfer configuration + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param trans : Number of transfers to update the transfer configuration to (1 - 1023) + * @return Nothing + */ +void Chip_DMA_SetupChannelTransferSize(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t trans); + +/** + * @brief Sets a DMA channel configuration as valid + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_SetChannelValid(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID); +} + +/** + * @brief Sets a DMA channel configuration as invalid + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_SetChannelInValid(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + Chip_DMA_ClearTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID); +} + +/** + * @brief Performs a software trigger of the DMA channel + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @return Nothing + */ +STATIC INLINE void Chip_DMA_SWTriggerChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch) +{ + Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_SWTRIG); +} + +/** + * @brief Sets up a DMA channel with the passed DMA transfer descriptor + * @param pDMA : The base of DMA controller on the chip + * @param ch : DMA channel ID + * @param desc : Pointer to DMA transfer descriptor + * @return false if the DMA channel was active, otherwise true + * @note This function will set the DMA descriptor in the SRAM table to the + * the passed descriptor. This function is only meant to be used when + * the DMA channel is not active and can be used to setup the + * initial transfer for a linked list or ping-pong buffer or just a + * single transfer without a next descriptor.
+ * + * If using this function to write the initial transfer descriptor in + * a linked list or ping-pong buffer configuration, it should contain a + * non-NULL 'next' field pointer. + */ +bool Chip_DMA_SetupTranChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch, DMA_CHDESC_T *desc); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/eeprom.h b/lpc_chip_15xx/inc/eeprom.h new file mode 100644 index 0000000..ef718ce --- /dev/null +++ b/lpc_chip_15xx/inc/eeprom.h @@ -0,0 +1,70 @@ +/* + * @brief Common EEPROM support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __EEPROM_H_ +#define __EEPROM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup COMMON_EEPROM CHIP: Common Chip EEPROM commands + * @ingroup CHIP_Common + * @{ + */ + +/** + * @brief Write data to EEPROM + * @param dstAdd : EEPROM address to be written to + * @param ptr : Pointer to buffer to write from + * @param byteswrt : Number of bytes to write to EEPROM + * @return An IAP response definition from iap.h + */ +uint8_t Chip_EEPROM_Write(uint32_t dstAdd, uint8_t *ptr, uint32_t byteswrt); + +/** + * @brief Read data from EEPROM + * @param srcAdd : EEPROM address to be read from + * @param ptr : Pointer to buffer to read to + * @param bytesrd : Number of bytes to read from EEPROM + * @return An IAP response definition from iap.h + */ +uint8_t Chip_EEPROM_Read(uint32_t srcAdd, uint8_t *ptr, uint32_t bytesrd); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __EEPROM_H_ */ diff --git a/lpc_chip_15xx/inc/error.h b/lpc_chip_15xx/inc/error.h new file mode 100644 index 0000000..f6a7d29 --- /dev/null +++ b/lpc_chip_15xx/inc/error.h @@ -0,0 +1,272 @@ +/* + * @brief Error code returned by Boot ROM drivers/library functions + * + * This file contains unified error codes to be used across driver, + * middleware, applications, hal and demo software. + * + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __LPC_ERROR_H__ +#define __LPC_ERROR_H__ + +/** Error code returned by Boot ROM drivers/library functions + * + * Error codes are a 32-bit value with : + * - The 16 MSB contains the peripheral code number + * - The 16 LSB contains an error code number associated to that peripheral + * + */ +typedef enum +{ + /**\b 0x00000000*/ LPC_OK=0, /**< enum value returned on Success */ + /**\b 0xFFFFFFFF*/ ERR_FAILED = -1, /**< enum value returned on general failure */ + /**\b 0xFFFFFFFE*/ ERR_TIME_OUT = -2, /**< enum value returned on general timeout */ + /**\b 0xFFFFFFFD*/ ERR_BUSY = -3, /**< enum value returned when resource is busy */ + + /* ISP related errors */ + ERR_ISP_BASE = 0x00000000, + /*0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1, + /*0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /* Source address not on word boundary */ + /*0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /* Destination address not on word or 256 byte boundary */ + /*0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED, + /*0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED, + /*0x00000006*/ ERR_ISP_COUNT_ERROR, /* Byte count is not multiple of 4 or is not a permitted value */ + /*0x00000007*/ ERR_ISP_INVALID_SECTOR, + /*0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK, + /*0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION, + /*0x0000000A*/ ERR_ISP_COMPARE_ERROR, + /*0x0000000B*/ ERR_ISP_BUSY, /* Flash programming hardware interface is busy */ + /*0x0000000C*/ ERR_ISP_PARAM_ERROR, /* Insufficient number of parameters */ + /*0x0000000D*/ ERR_ISP_ADDR_ERROR, /* Address not on word boundary */ + /*0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED, + /*0x0000000F*/ ERR_ISP_CMD_LOCKED, /* Command is locked */ + /*0x00000010*/ ERR_ISP_INVALID_CODE, /* Unlock code is invalid */ + /*0x00000011*/ ERR_ISP_INVALID_BAUD_RATE, + /*0x00000012*/ ERR_ISP_INVALID_STOP_BIT, + /*0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED, + /*0x00000014*/ ERR_ISP_INVALID_FLASH_UNIT, + /*0x00000015*/ ERR_ISP_USER_CODE_CHECKSUM, + /*0x00000016*/ ERR_ISP_SETTING_ACTIVE_PARTITION, + /*0x00000017*/ ERR_ISP_IRC_NO_POWER, + /*0x00000018*/ ERR_ISP_FLASH_NO_POWER, + /*0x00000019*/ ERR_ISP_EEPROM_NO_POWER, + /*0x0000001A*/ ERR_ISP_EEPROM_NO_CLOCK, + /*0x0000001B*/ ERR_ISP_FLASH_NO_CLOCK, + /*0x0000001C*/ ERR_ISP_REINVOKE_ISP_CONFIG, + + /* ROM API related errors */ + ERR_API_BASE = 0x00010000, + /**\b 0x00010001*/ ERR_API_INVALID_PARAMS = ERR_API_BASE + 1, /**< Invalid parameters*/ + /**\b 0x00010002*/ ERR_API_INVALID_PARAM1, /**< PARAM1 is invalid */ + /**\b 0x00010003*/ ERR_API_INVALID_PARAM2, /**< PARAM2 is invalid */ + /**\b 0x00010004*/ ERR_API_INVALID_PARAM3, /**< PARAM3 is invalid */ + /**\b 0x00010005*/ ERR_API_MOD_INIT, /**< API is called before module init */ + + /* SPIFI API related errors */ + ERR_SPIFI_BASE = 0x00020000, + /*0x00020001*/ ERR_SPIFI_DEVICE_ERROR =ERR_SPIFI_BASE+1, + /*0x00020002*/ ERR_SPIFI_INTERNAL_ERROR, + /*0x00020003*/ ERR_SPIFI_TIMEOUT, + /*0x00020004*/ ERR_SPIFI_OPERAND_ERROR, + /*0x00020005*/ ERR_SPIFI_STATUS_PROBLEM, + /*0x00020006*/ ERR_SPIFI_UNKNOWN_EXT, + /*0x00020007*/ ERR_SPIFI_UNKNOWN_ID, + /*0x00020008*/ ERR_SPIFI_UNKNOWN_TYPE, + /*0x00020009*/ ERR_SPIFI_UNKNOWN_MFG, + /*0x0002000A*/ ERR_SPIFI_NO_DEVICE, + /*0x0002000B*/ ERR_SPIFI_ERASE_NEEDED, + + SEC_AES_NO_ERROR=0, + /* Security API related errors */ + ERR_SEC_AES_BASE = 0x00030000, + /*0x00030001*/ ERR_SEC_AES_WRONG_CMD=ERR_SEC_AES_BASE+1, + /*0x00030002*/ ERR_SEC_AES_NOT_SUPPORTED, + /*0x00030003*/ ERR_SEC_AES_KEY_ALREADY_PROGRAMMED, + /*0x00030004*/ ERR_SEC_AES_DMA_CHANNEL_CFG, + /*0x00030005*/ ERR_SEC_AES_DMA_MUX_CFG, + /*0x00030006*/ SEC_AES_DMA_BUSY, + + /* USB device stack related errors */ + ERR_USBD_BASE = 0x00040000, + /**\b 0x00040001*/ ERR_USBD_INVALID_REQ = ERR_USBD_BASE + 1, /**< invalid request */ + /**\b 0x00040002*/ ERR_USBD_UNHANDLED, /**< Callback did not process the event */ + /**\b 0x00040003*/ ERR_USBD_STALL, /**< Stall the endpoint on which the call back is called */ + /**\b 0x00040004*/ ERR_USBD_SEND_ZLP, /**< Send ZLP packet on the endpoint on which the call back is called */ + /**\b 0x00040005*/ ERR_USBD_SEND_DATA, /**< Send data packet on the endpoint on which the call back is called */ + /**\b 0x00040006*/ ERR_USBD_BAD_DESC, /**< Bad descriptor*/ + /**\b 0x00040007*/ ERR_USBD_BAD_CFG_DESC,/**< Bad config descriptor*/ + /**\b 0x00040008*/ ERR_USBD_BAD_INTF_DESC,/**< Bad interface descriptor*/ + /**\b 0x00040009*/ ERR_USBD_BAD_EP_DESC,/**< Bad endpoint descriptor*/ + /**\b 0x0004000a*/ ERR_USBD_BAD_MEM_BUF, /**< Bad alignment of buffer passed. */ + /**\b 0x0004000b*/ ERR_USBD_TOO_MANY_CLASS_HDLR, /**< Too many class handlers. */ + + /* CGU related errors */ + ERR_CGU_BASE = 0x00050000, + /*0x00050001*/ ERR_CGU_NOT_IMPL=ERR_CGU_BASE+1, + /*0x00050002*/ ERR_CGU_INVALID_PARAM, + /*0x00050003*/ ERR_CGU_INVALID_SLICE, + /*0x00050004*/ ERR_CGU_OUTPUT_GEN, + /*0x00050005*/ ERR_CGU_DIV_SRC, + /*0x00050006*/ ERR_CGU_DIV_VAL, + /*0x00050007*/ ERR_CGU_SRC, + + /* I2C related errors */ + ERR_I2C_BASE = 0x00060000, + /*0x00060000*/ ERR_I2C_BUSY = ERR_I2C_BASE, + /*0x00060001*/ ERR_I2C_NAK, + /*0x00060002*/ ERR_I2C_BUFFER_OVERFLOW, + /*0x00060003*/ ERR_I2C_BYTE_COUNT_ERR, + /*0x00060004*/ ERR_I2C_LOSS_OF_ARBRITRATION, + /*0x00060005*/ ERR_I2C_SLAVE_NOT_ADDRESSED, + /*0x00060006*/ ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT, + /*0x00060007*/ ERR_I2C_GENERAL_FAILURE, + /*0x00060008*/ ERR_I2C_REGS_SET_TO_DEFAULT, + /*0x00060009*/ ERR_I2C_TIMEOUT, + /*0x0006000A*/ ERR_I2C_BUFFER_UNDERFLOW, + /*0x0006000B*/ ERR_I2C_PARAM, + + /* OTP related errors */ + ERR_OTP_BASE = 0x00070000, + /*0x00070001*/ ERR_OTP_WR_ENABLE_INVALID = ERR_OTP_BASE+1, + /*0x00070002*/ ERR_OTP_SOME_BITS_ALREADY_PROGRAMMED, + /*0x00070003*/ ERR_OTP_ALL_DATA_OR_MASK_ZERO, + /*0x00070004*/ ERR_OTP_WRITE_ACCESS_LOCKED, + /*0x00070005*/ ERR_OTP_READ_DATA_MISMATCH, + /*0x00070006*/ ERR_OTP_USB_ID_ENABLED, + /*0x00070007*/ ERR_OTP_ETH_MAC_ENABLED, + /*0x00070008*/ ERR_OTP_AES_KEYS_ENABLED, + /*0x00070009*/ ERR_OTP_ILLEGAL_BANK, + + /* UART related errors */ + ERR_UART_BASE = 0x00080000, + /*0x00080001*/ ERR_UART_RXD_BUSY = ERR_UART_BASE+1, //UART rxd is busy + /*0x00080002*/ ERR_UART_TXD_BUSY, //UART txd is busy + /*0x00080003*/ ERR_UART_OVERRUN_FRAME_PARITY_NOISE, //overrun err, frame err, parity err, RxNoise err + /*0x00080004*/ ERR_UART_UNDERRUN, //underrun err + /*0x00080005*/ ERR_UART_PARAM, //parameter is error + /*0x00080006*/ ERR_UART_BAUDRATE, //baudrate setting is error + + /* CAN related errors */ + ERR_CAN_BASE = 0x00090000, + /*0x00090001*/ ERR_CAN_BAD_MEM_BUF = ERR_CAN_BASE+1, + /*0x00090002*/ ERR_CAN_INIT_FAIL, + /*0x00090003*/ ERR_CANOPEN_INIT_FAIL, + + /* SPIFI Lite API related errors */ + ERR_SPIFI_LITE_BASE = 0x000A0000, + /*0x000A0001*/ ERR_SPIFI_LITE_INVALID_ARGUMENTS = ERR_SPIFI_LITE_BASE+1, + /*0x000A0002*/ ERR_SPIFI_LITE_BUSY, + /*0x000A0003*/ ERR_SPIFI_LITE_MEMORY_MODE_ON, + /*0x000A0004*/ ERR_SPIFI_LITE_MEMORY_MODE_OFF, + /*0x000A0005*/ ERR_SPIFI_LITE_IN_DMA, + /*0x000A0006*/ ERR_SPIFI_LITE_NOT_IN_DMA, + /*0x000A0100*/ PENDING_SPIFI_LITE, + + /* CLK related errors */ + ERR_CLK_BASE = 0x000B0000, + /*0x000B0001*/ ERR_CLK_NOT_IMPL=ERR_CLK_BASE+1, + /*0x000B0002*/ ERR_CLK_INVALID_PARAM, + /*0x000B0003*/ ERR_CLK_INVALID_SLICE, + /*0x000B0004*/ ERR_CLK_OUTPUT_GEN, + /*0x000B0005*/ ERR_CLK_DIV_SRC, + /*0x000B0006*/ ERR_CLK_DIV_VAL, + /*0x000B0007*/ ERR_CLK_SRC, + /*0x000B0008*/ ERR_CLK_PLL_FIN_TOO_SMALL, + /*0x000B0009*/ ERR_CLK_PLL_FIN_TOO_LARGE, + /*0x000B000A*/ ERR_CLK_PLL_FOUT_TOO_SMALL, + /*0x000B000B*/ ERR_CLK_PLL_FOUT_TOO_LARGE, + /*0x000B000C*/ ERR_CLK_PLL_NO_SOLUTION, + /*0x000B000D*/ ERR_CLK_PLL_MIN_PCT, + /*0x000B000E*/ ERR_CLK_PLL_MAX_PCT, + /*0x000B000F*/ ERR_CLK_OSC_FREQ, + /*0x000B0010*/ ERR_CLK_CFG, + /*0x000B0011*/ ERR_CLK_TIMEOUT, + /*0x000B0012*/ ERR_CLK_BASE_OFF, + /*0x000B0013*/ ERR_CLK_OFF_DEADLOCK, + + /*Power API*/ + ERR_PWR_BASE = 0x000C0000, + /*0x000C0001*/ PWR_ERROR_ILLEGAL_MODE=ERR_PWR_BASE+1, + /*0x000C0002*/ PWR_ERROR_CLOCK_FREQ_TOO_HIGH, + /*0x000C0003*/ PWR_ERROR_INVALID_STATE, + /*0x000C0004*/ PWR_ERROR_INVALID_CFG, + /*0x000C0005*/ PWR_ERROR_PVT_DETECT, + + /* DMA related errors */ + ERR_DMA_BASE = 0x000D0000, + /*0x000D0001*/ ERR_DMA_ERROR_INT=ERR_DMA_BASE+1, + /*0x000D0002*/ ERR_DMA_CHANNEL_NUMBER, + /*0x000D0003*/ ERR_DMA_CHANNEL_DISABLED, + /*0x000D0004*/ ERR_DMA_BUSY, + /*0x000D0005*/ ERR_DMA_NOT_ALIGNMENT, + /*0x000D0006*/ ERR_DMA_PING_PONG_EN, + /*0x000D0007*/ ERR_DMA_CHANNEL_VALID_PENDING, + /*0x000D0008*/ ERR_DMA_PARAM, + /*0x000D0009*/ ERR_DMA_QUEUE_EMPTY, + /*0x000D000A*/ ERR_DMA_GENERAL, + + /* SPI related errors */ + ERR_SPI_BASE = 0x000E0000, + /*0x000E0000*/ ERR_SPI_BUSY=ERR_SPI_BASE, + /*0x000E0001*/ ERR_SPI_RXOVERRUN, + /*0x000E0002*/ ERR_SPI_TXUNDERRUN, + /*0x000E0003*/ ERR_SPI_SELNASSERT, + /*0x000E0004*/ ERR_SPI_SELNDEASSERT, + /*0x000E0005*/ ERR_SPI_CLKSTALL, + /*0x000E0006*/ ERR_SPI_PARAM, + /*0x000E0007*/ ERR_SPI_INVALID_LENGTH, + + /* ADC related errors */ + ERR_ADC_BASE = 0x000F0000, + /*0x000F0001*/ ERR_ADC_OVERRUN=ERR_ADC_BASE+1, + /*0x000F0002*/ ERR_ADC_INVALID_CHANNEL, + /*0x000F0003*/ ERR_ADC_INVALID_SEQUENCE, + /*0x000F0004*/ ERR_ADC_INVALID_SETUP, + /*0x000F0005*/ ERR_ADC_PARAM, + /*0x000F0006*/ ERR_ADC_INVALID_LENGTH, + /*0x000F0007*/ ERR_ADC_NO_POWER, + + /* Debugger Mailbox related errors */ + ERR_DM_BASE = 0x00100000, + /*0x00100001*/ ERR_DM_NOT_ENTERED=ERR_DM_BASE+1, + /*0x00100002*/ ERR_DM_UNKNOWN_CMD, + /*0x00100003*/ ERR_DM_COMM_FAIL + +} ErrorCode_t; + +#ifndef offsetof +#define offsetof(s, m) (int) &(((s *) 0)->m) +#endif + +#define COMPILE_TIME_ASSERT(pred) switch (0) { \ + case 0: \ + case pred:; } + +#endif /* __LPC_ERROR_H__ */ diff --git a/lpc_chip_15xx/inc/fmc_15xx.h b/lpc_chip_15xx/inc/fmc_15xx.h new file mode 100644 index 0000000..d14b20c --- /dev/null +++ b/lpc_chip_15xx/inc/fmc_15xx.h @@ -0,0 +1,116 @@ +/* + * @brief FLASH Memory Controller (FMC) registers and control functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __FMC_15XX_H_ +#define __FMC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup FMC_15XX CHIP: LPC15xx FLASH Memory Controller driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief FLASH Memory Controller Unit register block structure + */ +typedef struct { /*!< FMC Structure */ + __I uint32_t RESERVED1[7]; + __IO uint32_t FMSSTART; + __IO uint32_t FMSSTOP; + __I uint32_t RESERVED2; + __I uint32_t FMSW[1]; +} LPC_FMC_T; + +/* Flash signature start and busy status bit */ +#define FMC_FLASHSIG_BUSY (1UL << 17) + +/** + * @brief Start computation of a signature for a FLASH memory range + * @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary + * @param stop : Ending FLASH address for computation, must be aligned on 16 byte boundary + * @return Nothing + * @note Only bits 20..4 are used for the FLASH signature computation. + * Use the Chip_FMC_IsSignatureBusy() function to determine when the + * signature computation operation is complete and use the + * Chip_FMC_GetSignature() function to get the computed signature. + */ +STATIC INLINE void Chip_FMC_ComputeSignature(uint32_t start, uint32_t stop) +{ + LPC_FMC->FMSSTART = (start >> 4); + LPC_FMC->FMSSTOP = (stop >> 4) | FMC_FLASHSIG_BUSY; +} + +/** + * @brief Start computation of a signature for a FLASH memory address and block count + * @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary + * @param blocks : Number of 16 byte blocks used for computation + * @return Nothing + * @note Only bits 20..4 are used for the FLASH signature computation. + * Use the Chip_FMC_IsSignatureBusy() function to determine when the + * signature computation operation is complete and the + * Chip_FMC_GetSignature() function to get the computed signature. + */ +STATIC INLINE void Chip_FMC_ComputeSignatureBlocks(uint32_t start, uint32_t blocks) +{ + Chip_FMC_ComputeSignature(start, (start + (blocks * 16))); +} + +/** + * @brief Check for signature geenration completion + * @return true if the signature computation is running, false if finished + */ +STATIC INLINE bool Chip_FMC_IsSignatureBusy(void) +{ + return (bool) ((LPC_FMC->FMSSTOP & FMC_FLASHSIG_BUSY) != 0); +} + +/** + * @brief Returns the generated FLASH signature value + * @param index : Not used, must be 0 + * @return the generated FLASH signature value + */ +STATIC INLINE uint32_t Chip_FMC_GetSignature(int index) +{ + return LPC_FMC->FMSW[index]; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FMC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/gpio_15xx.h b/lpc_chip_15xx/inc/gpio_15xx.h new file mode 100644 index 0000000..7f38aa8 --- /dev/null +++ b/lpc_chip_15xx/inc/gpio_15xx.h @@ -0,0 +1,471 @@ +/* + * @brief LPC15xx GPIO driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __GPIO_15XX_H_ +#define __GPIO_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup GPIO_15XX CHIP: LPC15xx GPIO driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief GPIO port register block structure + */ +typedef struct { /*!< GPIO_PORT Structure */ + __IO uint8_t B[128][32]; /*!< Offset 0x0000: Byte pin registers ports 0 to n; pins PIOn_0 to PIOn_31 */ + __IO uint32_t W[32][32]; /*!< Offset 0x1000: Word pin registers port 0 to n */ + __IO uint32_t DIR[32]; /*!< Offset 0x2000: Direction registers port n */ + __IO uint32_t MASK[32]; /*!< Offset 0x2080: Mask register port n */ + __IO uint32_t PIN[32]; /*!< Offset 0x2100: Portpin register port n */ + __IO uint32_t MPIN[32]; /*!< Offset 0x2180: Masked port register port n */ + __IO uint32_t SET[32]; /*!< Offset 0x2200: Write: Set register for port n Read: output bits for port n */ + __O uint32_t CLR[32]; /*!< Offset 0x2280: Clear port n */ + __O uint32_t NOT[32]; /*!< Offset 0x2300: Toggle port n */ +} LPC_GPIO_T; + +/** + * @brief Initialize GPIO block + * @param pGPIO : The base of GPIO peripheral on the chip + * @return Nothing + */ +void Chip_GPIO_Init(LPC_GPIO_T *pGPIO); + +/** + * @brief De-Initialize GPIO block + * @param pGPIO : The base of GPIO peripheral on the chip + * @return Nothing + */ +void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO); + +/** + * @brief Set a GPIO port/bit state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to set + * @param pin : GPIO pin to set + * @param setting : true for high, false for low + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_WritePortBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting) +{ + pGPIO->B[port][pin] = setting; +} + +/** + * @brief Set a GPIO pin state via the GPIO byte register + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to set + * @param setting : true for high, false for low + * @return Nothing + * @note This function replaces Chip_GPIO_WritePortBit() + */ +STATIC INLINE void Chip_GPIO_SetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool setting) +{ + pGPIO->B[port][pin] = setting; +} + +/** + * @brief Read a GPIO state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to read + * @param pin : GPIO pin to read + * @return true of the GPIO is high, false if low + * @note It is recommended to use the Chip_GPIO_GetPinState() function instead. + */ +STATIC INLINE bool Chip_GPIO_ReadPortBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin) +{ + return (bool) pGPIO->B[port][pin]; +} + +/** + * @brief Get a GPIO pin state via the GPIO byte register + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to get state for + * @return true if the GPIO is high, false if low + * @note This function replaces Chip_GPIO_ReadPortBit() + */ +STATIC INLINE bool Chip_GPIO_GetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + return (bool) pGPIO->B[port][pin]; +} + +/** + * @brief Set a GPIO direction + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to set + * @param bit : GPIO bit to set + * @param setting : true for output, false for input + * @return Nothing + * @note It is recommended to use the Chip_GPIO_SetPinDIROutput(), + * Chip_GPIO_SetPinDIRInput() or Chip_GPIO_SetPinDIR() functions instead + * of this function. + */ +void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit, bool setting); + +/** + * @brief Set GPIO direction for a single GPIO pin to an output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to set direction on as output + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetPinDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->DIR[port] |= 1UL << pin; +} + +/** + * @brief Set GPIO direction for a single GPIO pin to an input + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to set direction on as input + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetPinDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->DIR[port] &= ~(1UL << pin); +} + +/** + * @brief Set GPIO direction for a single GPIO pin + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to set direction for + * @param output : true for output, false for input + * @return Nothing + */ +void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output); + +/** + * @brief Read a GPIO direction (out or in) + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO port to read + * @param bit : GPIO bit to read + * @return true of the GPIO is an output, false if input + * @note It is recommended to use the Chip_GPIO_GetPinDIR() function instead. + */ +STATIC INLINE bool Chip_GPIO_ReadDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit) +{ + return (bool) (((pGPIO->DIR[port]) >> bit) & 1); +} + +/** + * @brief Get GPIO direction for a single GPIO pin + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : GPIO pin to get direction for + * @return true if the GPIO is an output, false if input + */ +STATIC INLINE bool Chip_GPIO_GetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + return (bool) (((pGPIO->DIR[port]) >> pin) & 1); +} + +/** + * @brief Set Direction for a GPIO port + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port Number + * @param bitValue : GPIO bit to set + * @param out : Direction value, 0 = input, !0 = output + * @return None + * @note Bits set to '0' are not altered. It is recommended to use the + * Chip_GPIO_SetPortDIR() function instead. + */ +void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out); + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pinMask : GPIO pin mask to set direction on as output (bits 0..b for pins 0..n) + * @return Nothing + * @note Sets multiple GPIO pins to the output direction, each bit's position that is + * high sets the corresponding pin number for that bit to an output. + */ +STATIC INLINE void Chip_GPIO_SetPortDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask) +{ + pGPIO->DIR[port] |= pinMask; +} + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an input + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pinMask : GPIO pin mask to set direction on as input (bits 0..b for pins 0..n) + * @return Nothing + * @note Sets multiple GPIO pins to the input direction, each bit's position that is + * high sets the corresponding pin number for that bit to an input. + */ +STATIC INLINE void Chip_GPIO_SetPortDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask) +{ + pGPIO->DIR[port] &= ~pinMask; +} + +/** + * @brief Set GPIO direction for a all selected GPIO pins to an input or output + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pinMask : GPIO pin mask to set direction on (bits 0..b for pins 0..n) + * @param outSet : Direction value, false = set as inputs, true = set as outputs + * @return Nothing + * @note Sets multiple GPIO pins to the input direction, each bit's position that is + * high sets the corresponding pin number for that bit to an input. + */ +void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask, bool outSet); + +/** + * @brief Get GPIO direction for a all GPIO pins + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @return a bitfield containing the input and output states for each pin + * @note For pins 0..n, a high state in a bit corresponds to an output state for the + * same pin, while a low state corresponds to an input state. + */ +STATIC INLINE uint32_t Chip_GPIO_GetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->DIR[port]; +} + +/** + * @brief Set GPIO port mask value for GPIO masked read and write + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @param mask : Mask value for read and write (only low bits are enabled) + * @return Nothing + * @note Controls which bits are set or unset when using the masked + * GPIO read and write functions. A low state indicates the pin is settable + * and readable via the masked write and read functions. + */ +STATIC INLINE void Chip_GPIO_SetPortMask(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t mask) +{ + pGPIO->MASK[port] = mask; +} + +/** + * @brief Get GPIO port mask value used for GPIO masked read and write + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : port Number + * @return Returns value set with the Chip_GPIO_SetPortMask() function. + * @note A high bit in the return value indicates that that GPIO pin for the + * port cannot be set using the masked write function. + */ +STATIC INLINE uint32_t Chip_GPIO_GetPortMask(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->MASK[port]; +} + +/** + * @brief Set all GPIO raw pin states (regardless of masking) + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param value : Value to set all GPIO pin states (0..n) to + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetPortValue(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value) +{ + pGPIO->PIN[port] = value; +} + +/** + * @brief Get all GPIO raw pin states (regardless of masking) + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @return Current (raw) state of all GPIO pins + */ +STATIC INLINE uint32_t Chip_GPIO_GetPortValue(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->PIN[port]; +} + +/** + * @brief Set all GPIO pin states, but mask via the MASKP0 register + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param value : Value to set all GPIO pin states (0..n) to + * @return Nothing + */ +STATIC INLINE void Chip_GPIO_SetMaskedPortValue(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value) +{ + pGPIO->MPIN[port] = value; +} + +/** + * @brief Get all GPIO pin statesm but mask via the MASKP0 register + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @return Current (masked) state of all GPIO pins + */ +STATIC INLINE uint32_t Chip_GPIO_GetMaskedPortValue(LPC_GPIO_T *pGPIO, uint8_t port) +{ + return pGPIO->MPIN[port]; +} + +/** + * @brief Set a GPIO port/bit to the high state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number + * @param bitValue : bit(s) in the port to set high + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. It is recommended to use the + * Chip_GPIO_SetPortOutHigh() function instead. + */ +STATIC INLINE void Chip_GPIO_SetValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue) +{ + pGPIO->SET[portNum] = bitValue; +} + +/** + * @brief Set selected GPIO output pins to the high state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pins : pins (0..n) to set high + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPortOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->SET[port] = pins; +} + +/** + * @brief Set an individual GPIO output pin to the high state + * @param pGPIO : The base of GPIO peripheral on the chip' + * @param port : GPIO Port number where @a pin is located + * @param pin : pin number (0..n) to set high + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPinOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->SET[port] = (1 << pin); +} + +/** + * @brief Set a GPIO port/bit to the low state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number + * @param bitValue : bit(s) in the port to set low + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_ClearValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue) +{ + pGPIO->CLR[portNum] = bitValue; +} + +/** + * @brief Set selected GPIO output pins to the low state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pins : pins (0..n) to set low + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPortOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->CLR[port] = pins; +} + +/** + * @brief Set an individual GPIO output pin to the low state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : pin number (0..n) to set low + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPinOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->CLR[port] = (1 << pin); +} + +/** + * @brief Toggle selected GPIO output pins to the opposite state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pins : pins (0..n) to toggle + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPortToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins) +{ + pGPIO->NOT[port] = pins; +} + +/** + * @brief Toggle an individual GPIO output pin to the opposite state + * @param pGPIO : The base of GPIO peripheral on the chip + * @param port : GPIO Port number where @a pin is located + * @param pin : pin number (0..n) to toggle + * @return None + * @note Any bit set as a '0' will not have it's state changed. This only + * applies to ports configured as an output. + */ +STATIC INLINE void Chip_GPIO_SetPinToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin) +{ + pGPIO->NOT[port] = (1 << pin); +} + +/** + * @brief Read current bit states for the selected port + * @param pGPIO : The base of GPIO peripheral on the chip + * @param portNum : port number to read + * @return Current value of GPIO port + * @note The current states of the bits for the port are read, regardless of + * whether the GPIO port bits are input or output. + */ +STATIC INLINE uint32_t Chip_GPIO_ReadValue(LPC_GPIO_T *pGPIO, uint8_t portNum) +{ + return pGPIO->PIN[portNum]; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIO_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/gpiogroup_15xx.h b/lpc_chip_15xx/inc/gpiogroup_15xx.h new file mode 100644 index 0000000..a8e5df8 --- /dev/null +++ b/lpc_chip_15xx/inc/gpiogroup_15xx.h @@ -0,0 +1,226 @@ +/* + * @brief LPC15xx GPIO group driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __GPIOGROUP_15XX_H_ +#define __GPIOGROUP_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup GPIOGP_15XX CHIP: LPC15xx GPIO group driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief GPIO grouped interrupt register block structure + */ +typedef struct { /*!< GPIO_GROUP_INTn Structure */ + __IO uint32_t CTRL; /*!< GPIO grouped interrupt control register */ + __I uint32_t RESERVED0[7]; + __IO uint32_t PORT_POL[8]; /*!< GPIO grouped interrupt port polarity register */ + __IO uint32_t PORT_ENA[8]; /*!< GPIO grouped interrupt port m enable register */ + uint32_t RESERVED1[1000]; +} LPC_GPIOGROUPINT_T; + +/** + * LPC15xx GPIO group bit definitions + */ +#define GPIOGR_INT (1 << 0) /*!< GPIO interrupt pending/clear bit */ +#define GPIOGR_COMB (1 << 1) /*!< GPIO interrupt OR(0)/AND(1) mode bit */ +#define GPIOGR_TRIG (1 << 2) /*!< GPIO interrupt edge(0)/level(1) mode bit */ + +/** + * @brief Initialize GPIO group interrupt block + * @param pGPIO : The base of GPIO group 0 peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_GPIOGP_Init(LPC_GPIOGROUPINT_T *pGPIO) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GINT); + Chip_SYSCTL_PeriphReset(RESET_GINT); +} + +/** + * @brief De-Initialize GPIO group interrupt block + * @param pGPIO : The base of GPIO group 0 peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_GPIOGP_DeInit(LPC_GPIOGROUPINT_T *pGPIO) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GINT); +} + +/** + * @brief Clear interrupt pending status for the selected group + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_ClearIntStatus(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + uint32_t temp; + + temp = pGPIOGPINT[group].CTRL; + pGPIOGPINT[group].CTRL = temp | GPIOGR_INT; +} + +/** + * @brief Returns current GPIO group inetrrupt pending status + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return true if the group interrupt is pending, otherwise false. + */ +STATIC INLINE bool Chip_GPIOGP_GetIntStatus(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + return (bool) ((pGPIOGPINT[group].CTRL & GPIOGR_INT) != 0); +} + +/** + * @brief Selected GPIO group functionality for trigger on any pin in group (OR mode) + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectOrMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL &= ~GPIOGR_COMB; +} + +/** + * @brief Selected GPIO group functionality for trigger on all matching pins in group (AND mode) + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectAndMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL |= GPIOGR_COMB; +} + +/** + * @brief Selected GPIO group functionality edge trigger mode + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectEdgeMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL &= ~GPIOGR_TRIG; +} + +/** + * @brief Selected GPIO group functionality level trigger mode + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectLevelMode(LPC_GPIOGROUPINT_T *pGPIOGPINT, uint8_t group) +{ + pGPIOGPINT[group].CTRL |= GPIOGR_TRIG; +} + +/** + * @brief Set selected pins for the group and port to low level trigger + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to select for low level (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectLowLevel(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_POL[port] &= ~pinMask; +} + +/** + * @brief Set selected pins for the group and port to high level trigger + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to select for high level (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + */ +STATIC INLINE void Chip_GPIOGP_SelectHighLevel(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_POL[port] |= pinMask; +} + +/** + * @brief Disabled selected pins for the group interrupt + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to disable interrupt for (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + * @note Disabled pins do not contrinute to the group interrupt. + */ +STATIC INLINE void Chip_GPIOGP_DisableGroupPins(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_ENA[port] &= ~pinMask; +} + +/** + * @brief Enable selected pins for the group interrupt + * @param pGPIOGPINT : Pointer to GPIO group register block + * @param group : GPIO group number + * @param port : GPIO port number + * @param pinMask : Or'ed value of pins to enable interrupt for (bit 0 = pin 0, 1 = pin1, etc.) + * @return None + * @note Enabled pins contribute to the group interrupt. + */ +STATIC INLINE void Chip_GPIOGP_EnableGroupPins(LPC_GPIOGROUPINT_T *pGPIOGPINT, + uint8_t group, + uint8_t port, + uint32_t pinMask) +{ + pGPIOGPINT[group].PORT_ENA[port] |= pinMask; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIOGROUP_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/i2c_common_15xx.h b/lpc_chip_15xx/inc/i2c_common_15xx.h new file mode 100644 index 0000000..1df6d55 --- /dev/null +++ b/lpc_chip_15xx/inc/i2c_common_15xx.h @@ -0,0 +1,313 @@ +/* + * @brief LPC15xx I2C driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __I2C_COMMON_15XX_H_ +#define __I2C_COMMON_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup I2C_15XX CHIP: LPC15xx I2C driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief I2C register block structure + */ +typedef struct { /* I2C0 Structure */ + __IO uint32_t CFG; /*!< I2C Configuration Register common for Master, Slave and Monitor */ + __IO uint32_t STAT; /*!< I2C Status Register common for Master, Slave and Monitor */ + __IO uint32_t INTENSET; /*!< I2C Interrupt Enable Set Register common for Master, Slave and Monitor */ + __O uint32_t INTENCLR; /*!< I2C Interrupt Enable Clear Register common for Master, Slave and Monitor */ + __IO uint32_t TIMEOUT; /*!< I2C Timeout value Register */ + __IO uint32_t CLKDIV; /*!< I2C Clock Divider Register */ + __I uint32_t INTSTAT; /*!< I2C Interrupt Status Register */ + __I uint32_t RESERVED0; + __IO uint32_t MSTCTL; /*!< I2C Master Control Register */ + __IO uint32_t MSTTIME; /*!< I2C Master Time Register for SCL */ + __IO uint32_t MSTDAT; /*!< I2C Master Data Register */ + __I uint32_t RESERVED1[5]; + __IO uint32_t SLVCTL; /*!< I2C Slave Control Register */ + __IO uint32_t SLVDAT; /*!< I2C Slave Data Register */ + __IO uint32_t SLVADR[4]; /*!< I2C Slave Address Registers */ + __IO uint32_t SLVQUAL0; /*!< I2C Slave Address Qualifier 0 Register */ + __I uint32_t RESERVED2[9]; + __I uint32_t MONRXDAT; /*!< I2C Monitor Data Register */ +} LPC_I2C_T; + +/* + * @brief I2C Configuration register Bit definition + */ +#define I2C_CFG_MSTEN (1 << 0) /*!< Master Enable/Disable Bit */ +#define I2C_CFG_SLVEN (1 << 1) /*!< Slave Enable/Disable Bit */ +#define I2C_CFG_MONEN (1 << 2) /*!< Monitor Enable/Disable Bit */ +#define I2C_CFG_TIMEOUTEN (1 << 3) /*!< Timeout Enable/Disable Bit */ +#define I2C_CFG_MONCLKSTR (1 << 4) /*!< Monitor Clock Stretching Bit */ +#define I2C_CFG_MASK ((uint32_t) 0x1F) /*!< Configuration register Mask */ + +/* + * @brief I2C Status register Bit definition + */ +#define I2C_STAT_MSTPENDING (1 << 0) /*!< Master Pending Status Bit */ +#define I2C_STAT_MSTSTATE (0x7 << 1) /*!< Master State Code */ +#define I2C_STAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Bit */ +#define I2C_STAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Bit */ +#define I2C_STAT_SLVPENDING (1 << 8) /*!< Slave Pending Status Bit */ +#define I2C_STAT_SLVSTATE (0x3 << 9) /*!< Slave State Code */ +#define I2C_STAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Bit */ +#define I2C_STAT_SLVIDX (0x3 << 12) /*!< Slave Address Index */ +#define I2C_STAT_SLVSEL (1 << 14) /*!< Slave Selected Bit */ +#define I2C_STAT_SLVDESEL (1 << 15) /*!< Slave Deselect Bit */ +#define I2C_STAT_MONRDY (1 << 16) /*!< Monitor Ready Bit */ +#define I2C_STAT_MONOV (1 << 17) /*!< Monitor Overflow Flag */ +#define I2C_STAT_MONACTIVE (1 << 18) /*!< Monitor Active Flag */ +#define I2C_STAT_MONIDLE (1 << 19) /*!< Monitor Idle Flag */ +#define I2C_STAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Flag */ +#define I2C_STAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Flag */ + +#define I2C_STAT_MSTCODE_IDLE (0) /*!< Master Idle State Code */ +#define I2C_STAT_MSTCODE_RXREADY (1) /*!< Master Receive Ready State Code */ +#define I2C_STAT_MSTCODE_TXREADY (2) /*!< Master Transmit Ready State Code */ +#define I2C_STAT_MSTCODE_NACKADR (3) /*!< Master NACK by slave on address State Code */ +#define I2C_STAT_MSTCODE_NACKDAT (4) /*!< Master NACK by slave on data State Code */ + +#define I2C_STAT_SLVCODE_ADDR (0) /*!< Master Idle State Code */ +#define I2C_STAT_SLVCODE_RX (1) /*!< Received data is available Code */ +#define I2C_STAT_SLVCODE_TX (2) /*!< Data can be transmitted Code */ + +/* + * @brief I2C Interrupt Enable Set register Bit definition + */ +#define I2C_INTENSET_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Enable Bit */ +#define I2C_INTENSET_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Enable Bit */ +#define I2C_INTENSET_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Enable Bit */ +#define I2C_INTENSET_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Enable Bit */ +#define I2C_INTENSET_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Enable Bit */ +#define I2C_INTENSET_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Enable Bit */ +#define I2C_INTENSET_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Enable Bit */ +#define I2C_INTENSET_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Enable Bit */ +#define I2C_INTENSET_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Enable Bit */ +#define I2C_INTENSET_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Enable Bit */ +#define I2C_INTENSET_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Enable Bit */ + +/* + * @brief I2C Interrupt Enable Clear register Bit definition + */ +#define I2C_INTENCLR_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Clear Bit */ +#define I2C_INTENCLR_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Clear Bit */ +#define I2C_INTENCLR_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Clear Bit */ +#define I2C_INTENCLR_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Clear Bit */ +#define I2C_INTENCLR_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Clear Bit */ +#define I2C_INTENCLR_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Clear Bit */ +#define I2C_INTENCLR_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Clear Bit */ +#define I2C_INTENCLR_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Clear Bit */ +#define I2C_INTENCLR_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Clear Bit */ +#define I2C_INTENCLR_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Clear Bit */ +#define I2C_INTENCLR_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Clear Bit */ + +/* + * @brief I2C TimeOut Value Macro + */ +#define I2C_TIMEOUT_VAL(n) (((uint32_t) ((n) - 1) & 0xFFF0) | 0x000F) /*!< Macro for Timeout value register */ + +/* + * @brief I2C Interrupt Status register Bit definition + */ +#define I2C_INTSTAT_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Status Bit */ +#define I2C_INTSTAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Status Bit */ +#define I2C_INTSTAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Status Bit */ +#define I2C_INTSTAT_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Status Bit */ +#define I2C_INTSTAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Status Bit */ +#define I2C_INTSTAT_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Status Bit */ +#define I2C_INTSTAT_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Status Bit */ +#define I2C_INTSTAT_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Status Bit */ +#define I2C_INTSTAT_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Status Bit */ +#define I2C_INTSTAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Status Bit */ +#define I2C_INTSTAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Status Bit */ + +/* + * @brief I2C Master Control register Bit definition + */ +#define I2C_MSTCTL_MSTCONTINUE (1 << 0) /*!< Master Continue Bit */ +#define I2C_MSTCTL_MSTSTART (1 << 1) /*!< Master Start Control Bit */ +#define I2C_MSTCTL_MSTSTOP (1 << 2) /*!< Master Stop Control Bit */ +#define I2C_MSTCTL_MSTDMA (1 << 3) /*!< Master DMA Enable Bit */ + +/* + * @brief I2C Master Time Register Field definition + */ +#define I2C_MSTTIME_MSTSCLLOW (0x07 << 0) /*!< Master SCL Low Time field */ +#define I2C_MSTTIME_MSTSCLHIGH (0x07 << 4) /*!< Master SCL High Time field */ + +/* + * @brief I2C Master Data Mask + */ +#define I2C_MSTDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Master data mask */ + +/* + * @brief I2C Slave Control register Bit definition + */ +#define I2C_SLVCTL_SLVCONTINUE (1 << 0) /*!< Slave Continue Bit */ +#define I2C_SLVCTL_SLVNACK (1 << 1) /*!< Slave NACK Bit */ +#define I2C_SLVCTL_SLVDMA (1 << 3) /*!< Slave DMA Enable Bit */ + +/* + * @brief I2C Slave Data Mask + */ +#define I2C_SLVDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Slave data mask */ + +/* + * @brief I2C Slave Address register Bit definition + */ +#define I2C_SLVADR_SADISABLE (1 << 0) /*!< Slave Address n Disable Bit */ +#define I2C_SLVADR_SLVADR (0x7F << 1) /*!< Slave Address field */ +#define I2C_SLVADR_MASK ((uint32_t) 0x00FF) /*!< Slave Address Mask */ + +/* + * @brief I2C Slave Address Qualifier 0 Register Bit definition + */ +#define I2C_SLVQUAL_QUALMODE0 (1 << 0) /*!< Slave Qualifier Mode Enable Bit */ +#define I2C_SLVQUAL_SLVQUAL0 (0x7F << 1) /*!< Slave Qualifier Address for Address 0 */ + +/* + * @brief I2C Monitor Data Register Bit definition + */ +#define I2C_MONRXDAT_DATA (0xFF << 0) /*!< Monitor Function Receive Data Field */ +#define I2C_MONRXDAT_MONSTART (1 << 8) /*!< Monitor Received Start Bit */ +#define I2C_MONRXDAT_MONRESTART (1 << 9) /*!< Monitor Received Repeated Start Bit */ +#define I2C_MONRXDAT_MONNACK (1 << 10) /*!< Monitor Received Nack Bit */ + +/** + * @brief Initialize I2C Interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function enables the I2C clock for both the master and + * slave interfaces if the I2C channel. + + */ +void Chip_I2C_Init(LPC_I2C_T *pI2C); + +/** + * @brief Shutdown I2C Interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function disables the I2C clock for both the master and + * slave interfaces if the I2C channel. + */ +void Chip_I2C_DeInit(LPC_I2C_T *pI2C); + +/** + * @brief Sets I2C Clock Divider registers + * @param pI2C : Pointer to selected I2C peripheral + * @param clkdiv : Clock Divider value for I2C, value is between (1 - 65536) + * @return Nothing + * @note The clock to I2C block is determined by the following formula (I2C_PCLK + * is the frequency of the system clock):
+ * I2C Clock Frequency = (I2C_PCLK)/clkdiv; + */ +static INLINE void Chip_I2C_SetClockDiv(LPC_I2C_T *pI2C, uint32_t clkdiv) +{ + if ((clkdiv >= 1) && (clkdiv <= 65536)) { + pI2C->CLKDIV = clkdiv - 1; + } + else { + pI2C->CLKDIV = 0; + } +} + +/** + * @brief Get I2C Clock Divider registers + * @param pI2C : Pointer to selected I2C peripheral + * @return Clock Divider value + * @note Return the divider value for the I2C block + * It is the CLKDIV register value + 1 + */ +static INLINE uint32_t Chip_I2C_GetClockDiv(LPC_I2C_T *pI2C) +{ + return (pI2C->CLKDIV & 0xFFFF) + 1; +} + +/** + * @brief Enable I2C Interrupts + * @param pI2C : Pointer to selected I2C peripheral + * @param intEn : ORed Value of I2C_INTENSET_* values to enable + * @return Nothing + */ +static INLINE void Chip_I2C_EnableInt(LPC_I2C_T *pI2C, uint32_t intEn) +{ + pI2C->INTENSET = intEn; +} + +/** + * @brief Disable I2C Interrupts + * @param pI2C : Pointer to selected I2C peripheral + * @param intClr : ORed Value of I2C_INTENSET_* values to disable + * @return Nothing + */ +static INLINE void Chip_I2C_DisableInt(LPC_I2C_T *pI2C, uint32_t intClr) +{ + pI2C->INTENCLR = intClr; +} + +/** + * @brief Disable I2C Interrupts + * @param pI2C : Pointer to selected I2C peripheral + * @param intClr : ORed Value of I2C_INTENSET_* values to disable + * @return Nothing + * @note It is recommended to use the Chip_I2C_DisableInt() function + * instead of this function. + */ +static INLINE void Chip_I2C_ClearInt(LPC_I2C_T *pI2C, uint32_t intClr) +{ + Chip_I2C_DisableInt(pI2C, intClr); +} + +/** + * @brief Returns pending I2C Interrupts + * @param pI2C : Pointer to selected I2C peripheral + * @return All pending interrupts, mask with I2C_INTENSET_* to determine specific interrupts + */ +static INLINE uint32_t Chip_I2C_GetPendingInt(LPC_I2C_T *pI2C) +{ + return pI2C->INTSTAT; +} + +/** + * @} + */ + + #ifdef __cplusplus +} +#endif + +#endif /* __I2C_COMMON_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/i2cm_15xx.h b/lpc_chip_15xx/inc/i2cm_15xx.h new file mode 100644 index 0000000..f2665ee --- /dev/null +++ b/lpc_chip_15xx/inc/i2cm_15xx.h @@ -0,0 +1,326 @@ +/* + * @brief LPC15xx I2C driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __I2CM_15XX_H_ +#define __I2CM_15XX_H_ + +#include "i2c_common_15xx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup I2CM_15XX CHIP: LPC15xx I2C master-only driver + * @ingroup I2C_15XX + * This driver only works in master mode. To describe the I2C transactions + * following symbols are used in driver documentation. + * + * Key to symbols + * ============== + * S (1 bit) : Start bit + * P (1 bit) : Stop bit + * Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0. + * A, NA (1 bit) : Acknowledge and Not-Acknowledge bit. + * Addr (7 bits): I2C 7 bit address. Note that this can be expanded as usual to + * get a 10 bit I2C address. + * Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh + * for 16 bit data. + * [..]: Data sent by I2C device, as opposed to data sent by the host adapter. + * @{ + */ + +/** I2CM_15XX_STATUS_TYPES I2C master transfer status types + * @{ + */ + +#define I2CM_STATUS_OK 0x00 /*!< Requested Request was executed successfully. */ +#define I2CM_STATUS_ERROR 0x01 /*!< Unknown error condition. */ +#define I2CM_STATUS_NAK_ADR 0x02 /*!< No acknowledgement received from slave during address phase. */ +#define I2CM_STATUS_BUS_ERROR 0x03 /*!< I2C bus error */ +#define I2CM_STATUS_NAK_DAT 0x04 /*!< No acknowledgement received from slave during address phase. */ +#define I2CM_STATUS_ARBLOST 0x05 /*!< Arbitration lost. */ +#define I2CM_STATUS_BUSY 0xFF /*!< I2C transmistter is busy. */ + +/** + * @} + */ + +/** + * @brief Master transfer data structure definitions + */ +typedef struct { + const uint8_t *txBuff; /*!< Pointer to array of bytes to be transmitted */ + uint8_t *rxBuff; /*!< Pointer memory where bytes received from I2C be stored */ + uint16_t txSz; /*!< Number of bytes in transmit array, + if 0 only receive transfer will be carried on */ + uint16_t rxSz; /*!< Number of bytes to received, + if 0 only transmission we be carried on */ + uint16_t status; /*!< Status of the current I2C transfer */ + uint8_t slaveAddr; /*!< 7-bit I2C Slave address */ +} I2CM_XFER_T; + +/** + * @brief Sets HIGH and LOW duty cycle registers + * @param pI2C : Pointer to selected I2C peripheral + * @param sclH : Number of I2C_PCLK cycles for the SCL HIGH time value between (2 - 9). + * @param sclL : Number of I2C_PCLK cycles for the SCL LOW time value between (2 - 9). + * @return Nothing + * @note The I2C clock divider should be set to the appropriate value before calling this function + * The I2C baud is determined by the following formula:
+ * I2C_bitFrequency = (I2C_PCLK)/(I2C_CLKDIV * (sclH + sclL))
+ * where I2C_PCLK is the frequency of the System clock and I2C_CLKDIV is I2C clock divider + */ +static INLINE void Chip_I2CM_SetDutyCycle(LPC_I2C_T *pI2C, uint16_t sclH, uint16_t sclL) +{ + pI2C->MSTTIME = (((sclH - 2) & 0x07) << 4) | ((sclL - 2) & 0x07); +} + +/** + * @brief Set up bus speed for LPC_I2C controller + * @param pI2C : Pointer to selected I2C peripheral + * @param busSpeed : I2C bus clock rate + * @return Nothing + * @note Per I2C specification the busSpeed should be + * @li 100000 for Standard mode + * @li 400000 for Fast mode + * @li 1000000 for Fast mode plus + * IOCON registers corresponding to I2C pads should be updated + * according to the bus mode. + */ +void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed); + +/** + * @brief Enable I2C Master interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note + */ +static INLINE void Chip_I2CM_Enable(LPC_I2C_T *pI2C) +{ + pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_MSTEN; +} + +/** + * @brief Disable I2C Master interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note + */ +static INLINE void Chip_I2CM_Disable(LPC_I2C_T *pI2C) +{ + pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_MSTEN; +} + +/** + * @brief Get I2C Status + * @param pI2C : Pointer to selected I2C peripheral + * @return I2C Status register value + * @note This function returns the value of the status register. + */ +static INLINE uint32_t Chip_I2CM_GetStatus(LPC_I2C_T *pI2C) +{ + return pI2C->STAT; +} + +/** + * @brief Clear I2C status bits (master) + * @param pI2C : Pointer to selected I2C peripheral + * @param clrStatus : Status bit to clear, ORed Value of I2C_STAT_MSTRARBLOSS and I2C_STAT_MSTSTSTPERR + * @return Nothing + * @note This function clears selected status flags. + */ +static INLINE void Chip_I2CM_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus) +{ + /* Clear Master Arbitration Loss and Start, Stop Error */ + pI2C->STAT = clrStatus & (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR); +} + +/** + * @brief Check if I2C Master is pending + * @param pI2C : Pointer to selected I2C peripheral + * @return Returns TRUE if the Master is pending else returns FALSE + * @note + */ +static INLINE bool Chip_I2CM_IsMasterPending(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_MSTPENDING) != 0; +} + +/** + * @brief Get current state of the I2C Master + * @param pI2C : Pointer to selected I2C peripheral + * @return Master State Code, a value in the range of 0 - 4 + * @note After the Master is pending this state code tells the reason + * for Master pending. + */ +static INLINE uint32_t Chip_I2CM_GetMasterState(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_MSTSTATE) >> 1; +} + +/** + * @brief Transmit START or Repeat-START signal on I2C bus + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function sets the controller to transmit START condition when + * the bus becomes free. This should be called only when master is pending. + * The function writes a complete value to Master Control register, ORing is not advised. + */ +static INLINE void Chip_I2CM_SendStart(LPC_I2C_T *pI2C) +{ + pI2C->MSTCTL = I2C_MSTCTL_MSTSTART; +} + +/** + * @brief Transmit STOP signal on I2C bus + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function sets the controller to transmit STOP condition. + * This should be called only when master is pending. The function writes a + * complete value to Master Control register, ORing is not advised. + */ +static INLINE void Chip_I2CM_SendStop(LPC_I2C_T *pI2C) +{ + pI2C->MSTCTL = I2C_MSTCTL_MSTSTOP; +} + +/** + * @brief Master Continue transfer operation + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function sets the master controller to continue transmission. + * This should be called only when master is pending. The function writes a + * complete value to Master Control register, ORing is not advised. + */ +static INLINE void Chip_I2CM_MasterContinue(LPC_I2C_T *pI2C) +{ + pI2C->MSTCTL = I2C_MSTCTL_MSTCONTINUE; +} + +/** + * @brief Transmit a single data byte through the I2C peripheral (master) + * @param pI2C : Pointer to selected I2C peripheral + * @param data : Byte to transmit + * @return Nothing + * @note This function attempts to place a byte into the I2C Master + * Data Register + * + */ +static INLINE void Chip_I2CM_WriteByte(LPC_I2C_T *pI2C, uint8_t data) +{ + pI2C->MSTDAT = (uint32_t) data; +} + +/** + * @brief Read a single byte data from the I2C peripheral (master) + * @param pI2C : Pointer to selected I2C peripheral + * @return A single byte of data read + * @note This function reads a byte from the I2C receive hold register + * regardless of I2C state. + */ +static INLINE uint8_t Chip_I2CM_ReadByte(LPC_I2C_T *pI2C) +{ + return (uint8_t) (pI2C->MSTDAT & I2C_MSTDAT_DATAMASK); +} + +/** + * @brief Transfer state change handler + * @param pI2C : Pointer to selected I2C peripheral + * @param xfer : Pointer to a I2CM_XFER_T structure see notes below + * @return Returns non-zero value on completion of transfer. The @a status + * member of @a xfer structure contains the current status of the + * transfer at the end of the call. + * @note + * The parameter @a xfer should be same as the one passed to Chip_I2CM_Xfer() + * routine. This function should be called from the I2C interrupt handler + * only when a master interrupt occurs. + */ +uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer); + +/** + * @brief Transmit and Receive data in master mode + * @param pI2C : Pointer to selected I2C peripheral + * @param xfer : Pointer to a I2CM_XFER_T structure see notes below + * @return Nothing + * @note + * The parameter @a xfer should have its member @a slaveAddr initialized + * to the 7-Bit slave address to which the master will do the xfer, Bit0 + * to bit6 should have the address and Bit8 is ignored. During the transfer + * no code (like event handler) must change the content of the memory + * pointed to by @a xfer. The member of @a xfer, @a txBuff and @a txSz be + * initialized to the memory from which the I2C must pick the data to be + * transfered to slave and the number of bytes to send respectively, similarly + * @a rxBuff and @a rxSz must have pointer to memroy where data received + * from slave be stored and the number of data to get from slave respectilvely. + * Following types of transfers are possible: + * - Write-only transfer: When @a rxSz member of @a xfer is set to 0. + * + * S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A] P + * + * - If I2CM_XFER_OPTION_IGNORE_NACK is set in @a options memeber + * + * S Addr Wr [A] txBuff0 [A or NA] ... txBuffN [A or NA] P + * + * - Read-only transfer: When @a txSz member of @a xfer is set to 0. + * + * S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P + * + * - If I2CM_XFER_OPTION_LAST_RX_ACK is set in @a options memeber + * + * S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] A P + * + * - Read-Write transfer: When @a rxSz and @ txSz members of @a xfer are non-zero. + * + * S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A] + * S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P + * + */ +void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer); + +/** + * @brief Transmit and Receive data in master mode + * @param pI2C : Pointer to selected I2C peripheral + * @param xfer : Pointer to a I2CM_XFER_T structure see notes below + * @return Returns non-zero value on succesful completion of transfer. + * @note + * This function operates same as Chip_I2CM_Xfer(), but is a blocking call. + */ +uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer); + +/** + * @} + */ + + #ifdef __cplusplus +} +#endif + +#endif /* __I2C_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/i2cs_15xx.h b/lpc_chip_15xx/inc/i2cs_15xx.h new file mode 100644 index 0000000..20ffba0 --- /dev/null +++ b/lpc_chip_15xx/inc/i2cs_15xx.h @@ -0,0 +1,337 @@ +/* + * @brief LPC15xx I2C slave driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __I2CS_15XX_H_ +#define __I2CS_15XX_H_ + +#include "i2c_common_15xx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup I2CS_15XX CHIP: LPC15xx I2C slave-only driver + * @ingroup I2C_15XX + * This driver only works in slave mode. + * @{ + */ + +/** @brief I2C slave service start callback + * This callback is called from the I2C slave handler when an I2C slave address is + * received and needs servicing. It's used to indicate the start of a slave transfer + * that will happen on the slave bus. + */ +typedef void (*I2CSlaveXferStart)(uint8_t addr); + +/** @brief I2C slave send data callback + * This callback is called from the I2C slave handler when an I2C slave address needs + * data to send. Return 0 to NACK the master and terminate the transfer, or return + * a non-0 value with the value to send in *data. + */ +typedef uint8_t (*I2CSlaveXferSend)(uint8_t *data); + +/** @brief I2C slave receive data callback + * This callback is called from the I2C slave handler when an I2C slave address has + * receive data. Return 0 to NACK the master and terminate the transfer, or return + * a non-0 value to continue the transfer. + */ +typedef uint8_t (*I2CSlaveXferRecv)(uint8_t data); + +/** @brief I2C slave service done callback + * This callback is called from the I2C slave handler when an I2C slave transfer is + * completed. It's used to indicate the end of a slave transfer. + */ +typedef void (*I2CSlaveXferDone)(void); + +/** + * Slave transfer are performed using 3 callbacks. These 3 callbacks handle most I2C + * slave transfer cases. When the slave is setup and a slave interrupt is receive + * and processed with the Chip_I2CS_XferHandler() function in the I2C interrupt handler, + * one of these 3 callbacks is called. The callbacks can be used for unsized transfers + * from the master. + * + * When an address is received, the SlaveXferAddr() callback is called with the + * received address. Only addresses enabled in the slave controller will be handled. + * The slave controller can support up to 4 slave addresses. + * + * If the master is going to perform a read operation, the SlaveXferSend() callback + * is called. Place the data byte to send in *data and return a non-0 value to the + * caller, or return 0 to NACK the master. (Note the master ACKS/NACKS to slave + * on reads, so this won't necessarily stop the slave transfer.)
+ * + * If the master performs a write operation, the SlaveXferRecv() callback is called + * with the received data. Return a non-0 value to the caller, or return 0 to NACK + * the master.
+ * + * Once the transfer completes, the SlaveXferDone() callback will be called.
+ */ +typedef struct { + I2CSlaveXferStart slaveStart; /*!< Called when an matching I2C slave address is received */ + I2CSlaveXferSend slaveSend; /*!< Called when a byte is needed to send to master */ + I2CSlaveXferRecv slaveRecv; /*!< Called when a byte is received from master */ + I2CSlaveXferDone slaveDone; /*!< Called when a slave transfer is complete */ +} I2CS_XFER_T; + +/** + * @brief Enable I2C slave interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note Do not call this function until the slave interface is fully configured. + */ +STATIC INLINE void Chip_I2CS_Enable(LPC_I2C_T *pI2C) +{ + pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_SLVEN; +} + +/** + * @brief Disable I2C slave interface + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + */ +STATIC INLINE void Chip_I2CS_Disable(LPC_I2C_T *pI2C) +{ + pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_SLVEN; +} + +/** + * @brief Get I2C Status + * @param pI2C : Pointer to selected I2C peripheral + * @return I2C Status register value + * @note This function returns the value of the status register. + */ +STATIC INLINE uint32_t Chip_I2CS_GetStatus(LPC_I2C_T *pI2C) +{ + return pI2C->STAT; +} + +/** + * @brief Clear I2C status bits (slave) + * @param pI2C : Pointer to selected I2C peripheral + * @param clrStatus : Status bit to clear, must be I2C_STAT_SLVDESEL + * @return Nothing + * @note This function clears selected status flags. + */ +STATIC INLINE void Chip_I2CS_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus) +{ + pI2C->STAT = clrStatus & I2C_STAT_SLVDESEL; +} + +/** + * @brief Check if I2C slave is pending + * @param pI2C : Pointer to selected I2C peripheral + * @return Returns TRUE if the slave is pending else returns FALSE + * @note + */ +STATIC INLINE bool Chip_I2CS_IsSlavePending(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_SLVPENDING) != 0; +} + +/** + * @brief Check if I2C slave is selected + * @param pI2C : Pointer to selected I2C peripheral + * @return Returns TRUE if the slave is is selected, otherwise FALSE + * @note + */ +STATIC INLINE bool Chip_I2CS_IsSlaveSelected(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_SLVSEL) != 0; +} + +/** + * @brief Check if I2C slave is deselected + * @param pI2C : Pointer to selected I2C peripheral + * @return Returns TRUE if the slave is is deselected, otherwise FALSE + * @note + */ +STATIC INLINE bool Chip_I2CS_IsSlaveDeSelected(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_SLVDESEL) != 0; +} + +/** + * @brief Get current state of the I2C slave + * @param pI2C : Pointer to selected I2C peripheral + * @return slave State Code, a value of type I2C_STAT_SLVCODE_* + * @note After the slave is pending this state code tells the reason + * for slave pending. + */ +STATIC INLINE uint32_t Chip_I2CS_GetSlaveState(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_SLVSTATE) >> 9; +} + +/** + * @brief Returns the current slave address match index + * @param pI2C : Pointer to selected I2C peripheral + * @return slave match index, 0 - 3 + */ +STATIC INLINE uint32_t Chip_I2CS_GetSlaveMatchIndex(LPC_I2C_T *pI2C) +{ + return (pI2C->STAT & I2C_STAT_SLVIDX) >> 12; +} + +/** + * @brief Slave Continue transfer operation (ACK) + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function sets the slave controller to continue transmission. + * This should be called only when slave is pending. The function writes a + * complete value to slave Control register, ORing is not advised. + */ +STATIC INLINE void Chip_I2CS_SlaveContinue(LPC_I2C_T *pI2C) +{ + pI2C->SLVCTL = I2C_SLVCTL_SLVCONTINUE; +} + +/** + * @brief Slave NACK operation + * @param pI2C : Pointer to selected I2C peripheral + * @return Nothing + * @note This function sets the slave controller to NAK the master. + */ +STATIC INLINE void Chip_I2CS_SlaveNACK(LPC_I2C_T *pI2C) +{ + pI2C->SLVCTL = I2C_SLVCTL_SLVNACK; +} + +/** + * @brief Transmit a single data byte through the I2C peripheral (slave) + * @param pI2C : Pointer to selected I2C peripheral + * @param data : Byte to transmit + * @return Nothing + * @note This function attempts to place a byte into the I2C slave + * Data Register + * + */ +STATIC INLINE void Chip_I2CS_WriteByte(LPC_I2C_T *pI2C, uint8_t data) +{ + pI2C->SLVDAT = (uint32_t) data; +} + +/** + * @brief Read a single byte data from the I2C peripheral (slave) + * @param pI2C : Pointer to selected I2C peripheral + * @return A single byte of data read + * @note This function reads a byte from the I2C receive hold register + * regardless of I2C state. + */ +STATIC INLINE uint8_t Chip_I2CS_ReadByte(LPC_I2C_T *pI2C) +{ + return (uint8_t) (pI2C->SLVDAT & I2C_SLVDAT_DATAMASK); +} + +/** + * @brief Set a I2C slave address for slave operation + * @param pI2C : Pointer to selected I2C peripheral + * @param slvNum : Possible slave address number, between 0 - 3 + * @param slvAddr : Slave Address for the index (7-bits, bit 7 = 0) + * @return Nothing + * @note Setting a slave address also enables the slave address. Do + * not 'pre-shift' the slave address. + */ +STATIC INLINE void Chip_I2CS_SetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum, uint8_t slvAddr) +{ + pI2C->SLVADR[slvNum] = (uint32_t) (slvAddr << 1); +} + +/** + * @brief Return a I2C programmed slave address + * @param pI2C : Pointer to selected I2C peripheral + * @param slvNum : Possible slave address number, between 0 - 3 + * @return Nothing + */ +STATIC INLINE uint8_t Chip_I2CS_GetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum) +{ + return (pI2C->SLVADR[slvNum] >> 1) & 0x7F; +} + +/** + * @brief Enable a I2C address + * @param pI2C : Pointer to selected I2C peripheral + * @param slvNum : Possible slave address number, between 0 - 3 + * @return Nothing + */ +STATIC INLINE void Chip_I2CS_EnableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum) +{ + pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) & ~I2C_SLVADR_SADISABLE; +} + +/** + * @brief Disable a I2C address + * @param pI2C : Pointer to selected I2C peripheral + * @param slvNum : Possible slave address number, between 0 - 3 + * @return Nothing + */ +STATIC INLINE void Chip_I2CS_DisableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum) +{ + pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) | I2C_SLVADR_SADISABLE; +} + +/** + * @brief Setup slave qialifier address + * @param pI2C : Pointer to selected I2C peripheral + * @param extend : true to extend I2C slave detect address 0 range, or false to match to corresponding bits + * @param slvAddr : Slave address qualifier, see SLVQUAL0 register in User Manual + * @return Nothing + * @note Do not 'pre-shift' the slave address. + */ +STATIC INLINE void Chip_I2CS_SetSlaveQual0(LPC_I2C_T *pI2C, bool extend, uint8_t slvNum) +{ + slvNum = slvNum << 1; + if (extend) { + slvNum |= I2C_SLVQUAL_QUALMODE0; + } + + pI2C->SLVQUAL0 = slvNum; +} + +/** + * @brief Slave transfer state change handler + * @param pI2C : Pointer to selected I2C peripheral + * @param xfers : Pointer to a I2CS_MULTI_XFER_T structure see notes below + * @return Returns non-zero value on completion of transfer + * @note See @ref I2CS_XFER_T for more information on this function. When using + * this function, the I2C_INTENSET_SLVPENDING and I2C_INTENSET_SLVDESEL interrupts + * should be enabled and setup in the I2C interrupt handler to call this function + * when they fire. + */ +uint32_t Chip_I2CS_XferHandler(LPC_I2C_T *pI2C, const I2CS_XFER_T *xfers); + +/** + * @} + */ + + #ifdef __cplusplus +} +#endif + +#endif /* __I2CS_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/iap.h b/lpc_chip_15xx/inc/iap.h new file mode 100644 index 0000000..febc395 --- /dev/null +++ b/lpc_chip_15xx/inc/iap.h @@ -0,0 +1,184 @@ +/* + * @brief Common IAP support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __IAP_H_ +#define __IAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup COMMON_IAP CHIP: Common Chip ISP/IAP commands and return codes + * @ingroup CHIP_Common + * @{ + */ + +/* IAP command definitions */ +#define IAP_PREWRRITE_CMD 50 /*!< Prepare sector for write operation command */ +#define IAP_WRISECTOR_CMD 51 /*!< Write Sector command */ +#define IAP_ERSSECTOR_CMD 52 /*!< Erase Sector command */ +#define IAP_BLANK_CHECK_SECTOR_CMD 53 /*!< Blank check sector */ +#define IAP_REPID_CMD 54 /*!< Read PartID command */ +#define IAP_READ_BOOT_CODE_CMD 55 /*!< Read Boot code version */ +#define IAP_COMPARE_CMD 56 /*!< Compare two RAM address locations */ +#define IAP_REINVOKE_ISP_CMD 57 /*!< Reinvoke ISP */ +#define IAP_READ_UID_CMD 58 /*!< Read UID */ +#define IAP_ERASE_PAGE_CMD 59 /*!< Erase page */ +#define IAP_EEPROM_WRITE 61 /*!< EEPROM Write command */ +#define IAP_EEPROM_READ 62 /*!< EEPROM READ command */ + +/* IAP response definitions */ +#define IAP_CMD_SUCCESS 0 /*!< Command is executed successfully */ +#define IAP_INVALID_COMMAND 1 /*!< Invalid command */ +#define IAP_SRC_ADDR_ERROR 2 /*!< Source address is not on word boundary */ +#define IAP_DST_ADDR_ERROR 3 /*!< Destination address is not on a correct boundary */ +#define IAP_SRC_ADDR_NOT_MAPPED 4 /*!< Source address is not mapped in the memory map */ +#define IAP_DST_ADDR_NOT_MAPPED 5 /*!< Destination address is not mapped in the memory map */ +#define IAP_COUNT_ERROR 6 /*!< Byte count is not multiple of 4 or is not a permitted value */ +#define IAP_INVALID_SECTOR 7 /*!< Sector number is invalid or end sector number is greater than start sector number */ +#define IAP_SECTOR_NOT_BLANK 8 /*!< Sector is not blank */ +#define IAP_SECTOR_NOT_PREPARED 9 /*!< Command to prepare sector for write operation was not executed */ +#define IAP_COMPARE_ERROR 10 /*!< Source and destination data not equal */ +#define IAP_BUSY 11 /*!< Flash programming hardware interface is busy */ +#define IAP_PARAM_ERROR 12 /*!< nsufficient number of parameters or invalid parameter */ +#define IAP_ADDR_ERROR 13 /*!< Address is not on word boundary */ +#define IAP_ADDR_NOT_MAPPED 14 /*!< Address is not mapped in the memory map */ +#define IAP_CMD_LOCKED 15 /*!< Command is locked */ +#define IAP_INVALID_CODE 16 /*!< Unlock code is invalid */ +#define IAP_INVALID_BAUD_RATE 17 /*!< Invalid baud rate setting */ +#define IAP_INVALID_STOP_BIT 18 /*!< Invalid stop bit setting */ +#define IAP_CRP_ENABLED 19 /*!< Code read protection enabled */ + +/* IAP_ENTRY API function type */ +typedef void (*IAP_ENTRY_T)(unsigned int[], unsigned int[]); + +/** + * @brief Prepare sector for write operation + * @param strSector : Start sector number + * @param endSector : End sector number + * @return Status code to indicate the command is executed successfully or not + * @note This command must be executed before executing "Copy RAM to flash" + * or "Erase Sector" command. + * The end sector must be greater than or equal to start sector number + */ +uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector); + +/** + * @brief Copy RAM to flash + * @param dstAdd : Destination FLASH address where data bytes are to be written + * @param srcAdd : Source RAM address where data bytes are to be read + * @param byteswrt : Number of bytes to be written + * @return Status code to indicate the command is executed successfully or not + * @note The addresses should be a 256 byte boundary and the number of bytes + * should be 256 | 512 | 1024 | 4096 + */ +uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt); + +/** + * @brief Erase sector + * @param strSector : Start sector number + * @param endSector : End sector number + * @return Status code to indicate the command is executed successfully or not + * @note The end sector must be greater than or equal to start sector number + */ +uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector); + +/** + * @brief Blank check a sector or multiples sector of on-chip flash memory + * @param strSector : Start sector number + * @param endSector : End sector number + * @return Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK + * @note The end sector must be greater than or equal to start sector number + */ +// FIXME - There are two return value (result[0] & result[1] +// Result0:Offset of the first non blank word location if the Status Code is +// SECTOR_NOT_BLANK. +// Result1:Contents of non blank word location. +uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector); + +/** + * @brief Read part identification number + * @return Part identification number + */ +uint32_t Chip_IAP_ReadPID(void); + +/** + * @brief Read boot code version number + * @return Boot code version number + */ +uint32_t Chip_IAP_ReadBootCode(void); + +/** + * @brief Compare the memory contents at two locations + * @param dstAdd : Destination of the RAM address of data bytes to be compared + * @param srcAdd : Source of the RAM address of data bytes to be compared + * @param bytescmp : Number of bytes to be compared + * @return Offset of the first mismatch of the status code is COMPARE_ERROR + * @note The addresses should be a word boundary and number of bytes should be + * a multiply of 4 + */ +uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp); + +/** + * @brief IAP reinvoke ISP to invoke the bootloader in ISP mode + * @return none + */ +uint8_t Chip_IAP_ReinvokeISP(void); + +/** + * @brief Read the unique ID + * @return Status code to indicate the command is executed successfully or not + */ +uint32_t Chip_IAP_ReadUID(uint32_t* uid); + +/** + * @brief Erase a page or multiple papers of on-chip flash memory + * @param strPage : Start page number + * @param endPage : End page number + * @return Status code to indicate the command is executed successfully or not + * @note The page number must be greater than or equal to start page number + */ +// FIXME - There are four return value +// Result0:The first 32-bit word (at the lowest address) +// Result1:The second 32-bit word. +// Result2:The third 32-bit word. +// Result3:The fourth 32-bit word. +uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __IAP_H_ */ diff --git a/lpc_chip_15xx/inc/inmux_15xx.h b/lpc_chip_15xx/inc/inmux_15xx.h new file mode 100644 index 0000000..214e739 --- /dev/null +++ b/lpc_chip_15xx/inc/inmux_15xx.h @@ -0,0 +1,315 @@ +/* + * @brief LPC15xx Input Mux Registers and Driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __INMUX_15XX_H_ +#define __INMUX_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup INMUX_15XX CHIP: LPC15xx Input Mux Registers and Driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15xx Input Mux Register Block Structure + */ +typedef struct { /*!< INMUX Structure */ + __IO uint32_t SCT0_INMUX[7]; /*!< Input mux registers for SCT0 inputs */ + __I uint32_t RESERVED1[1]; + __IO uint32_t SCT1_INMUX[7]; /*!< Input mux registers for SCT1 inputs */ + __I uint32_t RESERVED2[1]; + __IO uint32_t SCT2_INMUX[3]; /*!< Input mux registers for SCT2 inputs */ + __I uint32_t RESERVED3[5]; + __IO uint32_t SCT3_INMUX[3]; /*!< Input mux registers for SCT3 inputs */ + __I uint32_t RESERVED4[5]; + __I uint32_t RESERVED4A[16]; + __IO uint32_t PINTSEL[8]; /*!< Pin interrupt select registers */ + __IO uint32_t DMA_ITRIG_INMUX[18]; /*!< Input mux register for DMA trigger inputs */ + __I uint32_t RESERVED5[6]; + __IO uint32_t DMA_INMUX[4]; /*!< Input mux register for DMA trigger inputs */ + __I uint32_t RESERVED6[4]; + __IO uint32_t FREQMEAS_REF; /*!< Clock selection for frequency measurement ref clock */ + __IO uint32_t FREQMEAS_TARGET; /*!< Clock selection for frequency measurement target clock */ +} LPC_INMUX_T; + +/* SCT input mux mapping selections for SCT0 inputs 0-6 */ +typedef enum { + SCT0_INMUX_PIO0_2 = 0, + SCT0_INMUX_PIO0_3, + SCT0_INMUX_PIO0_17, + SCT0_INMUX_PIO0_30, + SCT0_INMUX_PIO1_6, + SCT0_INMUX_PIO1_7, + SCT0_INMUX_PIO1_12, + SCT0_INMUX_PIO1_13, + SCT0_INMUX_SCT1_OUT4, + SCT0_INMUX_SCT2_OUT4, + SCT0_INMUX_SCT2_OUT5, + SCT0_INMUX_ADC0_THCMP_IRQ, + SCT0_INMUX_ADC1_THCMP_IRQ, + SCT0_INMUX_ACMP0_OUT, + SCT0_INMUX_ACMP1_OUT, + SCT0_INMUX_ACMP2_OUT, + SCT0_INMUX_ACMP3_OUT, + SCT0_INMUX_SCTIPU_ABORT, + SCT0_INMUX_SCTIPU_SAMPLE0, + SCT0_INMUX_SCTIPU_SAMPLE1, + SCT0_INMUX_SCTIPU_SAMPLE2, + SCT0_INMUX_SCTIPU_SAMPLE3, + SCT0_INMUX_DEBUG_HALTED +} SCT0_INMUX_T; + +/** + * @brief Selects an input source for SCT0 input 0 to 6 + * @param input : SCT0 input to use, 0 - 6 + * @param src : Source to map to the SCT input + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SelectSCT0Src(uint8_t input, SCT0_INMUX_T src) +{ + LPC_INMUX->SCT0_INMUX[input] = (uint32_t) src; +} + +/* SCT input mux mapping selections for SCT1 inputs 0-6 */ +typedef enum { + SCT1_INMUX_PIO0_15 = 0, + SCT1_INMUX_PIO0_16, + SCT1_INMUX_PIO0_21, + SCT1_INMUX_PIO0_31, + SCT1_INMUX_PIO1_4, + SCT1_INMUX_PIO1_5, + SCT1_INMUX_PIO1_15, + SCT1_INMUX_PIO1_16, + SCT1_INMUX_SCT0_OUT4, + SCT1_INMUX_SCT3_OUT4, + SCT1_INMUX_SCT3_OUT5, + SCT1_INMUX_ADC0_THCMP_IRQ, + SCT1_INMUX_ADC1_THCMP_IRQ, + SCT1_INMUX_ACMP0_OUT, + SCT1_INMUX_ACMP1_OUT, + SCT1_INMUX_ACMP2_OUT, + SCT1_INMUX_ACMP3_OUT, + SCT1_INMUX_SCTIPU_ABORT, + SCT1_INMUX_SCTIPU_SAMPLE0, + SCT1_INMUX_SCTIPU_SAMPLE1, + SCT1_INMUX_SCTIPU_SAMPLE2, + SCT1_INMUX_SCTIPU_SAMPLE3, + SCT1_INMUX_DEBUG_HALTED +} SCT1_INMUX_T; + +/** + * @brief Selects an input source for SCT1 input 0 to 6 + * @param input : SCT1 input to use, 0 - 6 + * @param src : Source to map to the SCT input + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SelectSCT1Src(uint8_t input, SCT1_INMUX_T src) +{ + LPC_INMUX->SCT1_INMUX[input] = (uint32_t) src; +} + +/* SCT input mux mapping selections for SCT2 inputs 0-2 */ +typedef enum { + SCT2_INMUX_PIO0_4 = 0, + SCT2_INMUX_PIO0_27, + SCT2_INMUX_PIO1_18, + SCT2_INMUX_PIO1_19, + SCT2_INMUX_SCT0_OUT4, + SCT2_INMUX_SCT0_OUT5, + SCT2_INMUX_SCT0_OUT7, + SCT2_INMUX_SCT0_OUT8, + SCT2_INMUX_ADC0_THCMP_IRQ, + SCT2_INMUX_ADC1_THCMP_IRQ, + SCT2_INMUX_ACMP0_OUT, + SCT2_INMUX_ACMP1_OUT, + SCT2_INMUX_ACMP2_OUT, + SCT2_INMUX_ACMP3_OUT, + SCT2_INMUX_SCTIPU_ABORT, + SCT2_INMUX_SCTIPU_SAMPLE0, + SCT2_INMUX_SCTIPU_SAMPLE1, + SCT2_INMUX_SCTIPU_SAMPLE2, + SCT2_INMUX_SCTIPU_SAMPLE3, + SCT2_INMUX_USB_FRAME_TOGGLE, + SCT2_INMUX_DEBUG_HALTED +} SCT2_INMUX_T; + +/** + * @brief Selects an input source for SCT2 input 0 to 2 + * @param input : SCT2 input to use, 0 - 2 + * @param src : Source to map to the SCT input + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SelectSCT2Src(uint8_t input, SCT2_INMUX_T src) +{ + LPC_INMUX->SCT2_INMUX[input] = (uint32_t) src; +} + +/* SCT input mux mapping selections for SCT3 inputs 0-2 */ +typedef enum { + SCT3_INMUX_PIO0_7 = 0, + SCT3_INMUX_PIO1_11, + SCT3_INMUX_PIO1_21, + SCT3_INMUX_PIO1_22, + SCT3_INMUX_SCT1_OUT4, + SCT3_INMUX_SCT1_OUT5, + SCT3_INMUX_SCT1_OUT7, + SCT3_INMUX_SCT1_OUT8, + SCT3_INMUX_ADC0_THCMP_IRQ, + SCT3_INMUX_ADC1_THCMP_IRQ, + SCT3_INMUX_ACMP0_OUT, + SCT3_INMUX_ACMP1_OUT, + SCT3_INMUX_ACMP2_OUT, + SCT3_INMUX_ACMP3_OUT, + SCT3_INMUX_SCTIPU_ABORT3, + SCT3_INMUX_SCTIPU_SAMPLE0, + SCT3_INMUX_SCTIPU_SAMPLE1, + SCT3_INMUX_SCTIPU_SAMPLE2, + SCT3_INMUX_SCTIPU_SAMPLE3, + SCT3_INMUX_USB_FRAME_TOGGLE, + SCT3_INMUX_DEBUG_HALTED +} SCT3_INMUX_T; + +/** + * @brief Selects an input source for SCT3 input 0 to 2 + * @param input : SCT3 input to use, 0 - 2 + * @param src : Source to map to the SCT input + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SelectSCT3Src(uint8_t input, SCT3_INMUX_T src) +{ + LPC_INMUX->SCT3_INMUX[input] = (uint32_t) src; +} + +/** + * @brief GPIO Pin Interrupt Pin Select (sets PINTSEL register) + * @param pintSel : GPIO PINTSEL interrupt, should be: 0 to 7 + * @param portNum : GPIO port number interrupt, should be: 0 to 1 + * @param pinNum : GPIO pin number Interrupt, should be: 0 to 31 + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_PinIntSel(uint8_t pintSel, uint8_t portNum, uint8_t pinNum) +{ + LPC_INMUX->PINTSEL[pintSel] = (portNum * 32) + pinNum; +} + +/* DMA triggers that can mapped to DMA channels */ +typedef enum { + DMATRIG_ADC0_SEQA_IRQ = 0, /*!< ADC0 sequencer A interrupt as trigger */ + DMATRIG_ADC0_SEQB_IRQ, /*!< ADC0 sequencer B interrupt as trigger */ + DMATRIG_ADC1_SEQA_IRQ, /*!< ADC1 sequencer A interrupt as trigger */ + DMATRIG_ADC1_SEQB_IRQ, /*!< ADC1 sequencer B interrupt as trigger */ + DMATRIG_SCT0_DMA0, /*!< SCT 0, DMA 0 as trigger */ + DMATRIG_SCT0_DMA1, /*!< SCT 1, DMA 1 as trigger */ + DMATRIG_SCT1_DMA0, /*!< SCT 0, DMA 0 as trigger */ + DMATRIG_SCT1_DMA1, /*!< SCT 1, DMA 1 as trigger */ + DMATRIG_SCT2_DMA0, /*!< SCT 2, DMA 0 as trigger */ + DMATRIG_SCT2_DMA1, /*!< SCT 2, DMA 1 as trigger */ + DMATRIG_SCT3_DMA0, /*!< SCT 3, DMA 0 as trigger */ + DMATRIG_SCT3_DMA1, /*!< SCT 3, DMA 1 as trigger */ + DMATRIG_ACMP0_OUT, /*!< Analog comparator 0 output as trigger */ + DMATRIG_ACMP1_OUT, /*!< Analog comparator 1 output as trigger */ + DMATRIG_ACMP2_OUT, /*!< Analog comparator 2 output as trigger */ + DMATRIG_ACMP3_OUT, /*!< Analog comparator 3 output as trigger */ + DMATRIG_OUTMUX0, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX1, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX2, /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ + DMATRIG_OUTMUX3 /*!< DMA trigger tied to this source, Select with Chip_INMUX_SetDMAOutMux */ +} DMA_TRIGSRC_T; + +/** + * @brief Select a trigger source for a DMA channel + * @param ch : DMA channel number + * @param trig : Trigger source for the DMA channel + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetDMATrigger(uint8_t ch, DMA_TRIGSRC_T trig) +{ + LPC_INMUX->DMA_ITRIG_INMUX[ch] = (uint32_t) trig; +} + +/** + * @brief Selects a DMA trigger source for the DMATRIG_OUTMUXn IDs + * @param index : Select 0 to 3 to sets the source for DMATRIG_OUTMUX0 to DMATRIG_OUTMUX3 + * @param dmaCh : DMA channel to select for DMATRIG_OUTMUXn source + * @return Nothing + * @note This function sets the DMA trigger (out) source used with the DMATRIG_OUTMUXn + * trigger source. + */ +STATIC INLINE void Chip_INMUX_SetDMAOutMux(uint8_t index, uint8_t dmaCh) +{ + LPC_INMUX->DMA_INMUX[index] = (uint32_t) dmaCh; +} + +/* Freqeuency mearure reference and target clock sources */ +typedef enum { + FREQMSR_MAIN_OSC = 0, /*!< System oscillator */ + FREQMSR_IRC, /*!< Internal RC (IRC) oscillator */ + FREQMSR_WDOSC, /*!< Watchdog oscillator */ + FREQMSR_32KHZOSC, /*!< 32KHz (RTC) oscillator rate */ + FREQMSR_USB_FTOGGLE, /*!< USB FTOGGLE rate */ + FREQMSR_PIO0_5, /*!< External pin PIO0_5 as input rate */ + FREQMSR_PIO0_19, /*!< External pin PIO0_19 as input rate */ + FREQMSR_PIO0_30, /*!< External pin PIO0_30 as input rate */ + FREQMSR_PIO1_27 /*!< External pin PIO1_27 as input rate */ +} FREQMSR_SRC_T; + +/** + * @brief Selects a reference clock used with the frequency measure function + * @param ref : Frequency measure function reference clock + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetFreqMeasRefClock(FREQMSR_SRC_T ref) +{ + LPC_INMUX->FREQMEAS_REF = (uint32_t) ref; +} + +/** + * @brief Selects a target clock used with the frequency measure function + * @param targ : Frequency measure function reference clock + * @return Nothing + */ +STATIC INLINE void Chip_INMUX_SetFreqMeasTargClock(FREQMSR_SRC_T targ) +{ + LPC_INMUX->FREQMEAS_TARGET = (uint32_t) targ; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __INMUX_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/iocon_15xx.h b/lpc_chip_15xx/inc/iocon_15xx.h new file mode 100644 index 0000000..7435d74 --- /dev/null +++ b/lpc_chip_15xx/inc/iocon_15xx.h @@ -0,0 +1,131 @@ +/* + * @brief LPC15xx IOCON driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __IOCON_15XX_H_ +#define __IOCON_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup IOCON_15XX CHIP: LPC15xx IO Control driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15XX IO Configuration Unit register block structure + */ +typedef struct { /*!< LPC15XX IOCON Structure */ + __IO uint32_t PIO[3][32]; +} LPC_IOCON_T; + +/** + * @brief Array of IOCON pin definitions passed to Chip_IOCON_SetPinMuxing() must be in this format + */ +typedef struct { + uint32_t port : 8; /* Pin port */ + uint32_t pin : 8; /* Pin number */ + uint32_t modefunc : 16; /* Function and mode */ +} PINMUX_GRP_T; + +/** + * IOCON function and mode selection definitions + * See the User Manual for specific modes and functions supported by the + * various LPC15XX pins. + */ +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_MODE_INACT (0x0 << 3) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << 3) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << 3) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << 3) /*!< Selects pin repeater function */ +#define IOCON_HYS_EN (0x1 << 5) /*!< Enables hysteresis */ +#define IOCON_INV_EN (0x1 << 6) /*!< Enables invert function on input */ +#define IOCON_ADMODE_EN (0x0 << 7) /*!< Enables analog input function (analog pins only) */ +#define IOCON_DIGMODE_EN (0x1 << 7) /*!< Enables digital function (analog pins only) */ +#define IOCON_SFI2C_EN (0x0 << 8) /*!< I2C standard mode/fast-mode */ +#define IOCON_STDI2C_EN (0x1 << 8) /*!< I2C standard I/O functionality */ +#define IOCON_FASTI2C_EN (0x2 << 8) /*!< I2C Fast-mode Plus */ +#define IOCON_OPENDRAIN_EN (0x1 << 10) /*!< Enables open-drain function */ +#define IOCON_S_MODE_0CLK (0x0 << 11) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK (0x1 << 11) /*!< Input pulses shorter than 1 filter clock are rejected */ +#define IOCON_S_MODE_2CLK (0x2 << 11) /*!< Input pulses shorter than 2 filter clock2 are rejected */ +#define IOCON_S_MODE_3CLK (0x3 << 11) /*!< Input pulses shorter than 3 filter clock2 are rejected */ +#define IOCON_S_MODE(clks) ((clks) << 11) /*!< Select clocks for digital input filter mode */ +#define IOCON_CLKDIV(div) ((div) << 13) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ + +/** + * @brief Sets I/O Control pin mux + * @param pIOCON : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @param pin : GPIO pin to mux + * @param modefunc : OR'ed values or type IOCON_* + * @return Nothing + */ +STATIC INLINE void Chip_IOCON_PinMuxSet(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin, uint32_t modefunc) +{ + pIOCON->PIO[port][pin] = modefunc; +} + +/** + * @brief I/O Control pin mux + * @param pIOCON : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @param pin : GPIO pin to mux + * @param mode : OR'ed values or type IOCON_* + * @param func : Pin function, value of type IOCON_FUNC? + * @return Nothing + */ +STATIC INLINE void Chip_IOCON_PinMux(LPC_IOCON_T *pIOCON, uint8_t port, uint8_t pin, uint16_t mode, uint8_t func) +{ + Chip_IOCON_PinMuxSet(pIOCON, port, pin, (uint32_t) (mode | func)); +} + +/** + * @brief Set all I/O Control pin muxing + * @param pIOCON : The base of IOCON peripheral on the chip + * @param pinArray : Pointer to array of pin mux selections + * @param arrayLength : Number of entries in pinArray + * @return Nothing + */ +void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T *pinArray, uint32_t arrayLength); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __IOCON_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/lpc_types.h b/lpc_chip_15xx/inc/lpc_types.h new file mode 100644 index 0000000..772143e --- /dev/null +++ b/lpc_chip_15xx/inc/lpc_types.h @@ -0,0 +1,216 @@ +/* + * @brief Common types used in LPC functions + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __LPC_TYPES_H_ +#define __LPC_TYPES_H_ + +#include +#include + +/** @defgroup LPC_Types CHIP: LPC Common Types + * @ingroup CHIP_Common + * @{ + */ + +/** @defgroup LPC_Types_Public_Types LPC Public Types + * @{ + */ + +/** + * @brief Boolean Type definition + */ +typedef enum {FALSE = 0, TRUE = !FALSE} Bool; + +/** + * @brief Boolean Type definition + */ +#if !defined(__cplusplus) +// typedef enum {false = 0, true = !false} bool; +#endif + +/** + * @brief Flag Status and Interrupt Flag Status type definition + */ +typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState; +#define PARAM_SETSTATE(State) ((State == RESET) || (State == SET)) + +/** + * @brief Functional State Definition + */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define PARAM_FUNCTIONALSTATE(State) ((State == DISABLE) || (State == ENABLE)) + +/** + * @ Status type definition + */ +typedef enum {ERROR = 0, SUCCESS = !ERROR} Status; + +/** + * Read/Write transfer type mode (Block or non-block) + */ +typedef enum { + NONE_BLOCKING = 0, /**< None Blocking type */ + BLOCKING, /**< Blocking type */ +} TRANSFER_BLOCK_T; + +/** Pointer to Function returning Void (any number of parameters) */ +typedef void (*PFV)(); + +/** Pointer to Function returning int32_t (any number of parameters) */ +typedef int32_t (*PFI)(); + +/** + * @} + */ + +/** @defgroup LPC_Types_Public_Macros LPC Public Macros + * @{ + */ + +/* _BIT(n) sets the bit at position "n" + * _BIT(n) is intended to be used in "OR" and "AND" expressions: + * e.g., "(_BIT(3) | _BIT(7))". + */ +#undef _BIT +/* Set bit macro */ +#define _BIT(n) (1 << (n)) + +/* _SBF(f,v) sets the bit field starting at position "f" to value "v". + * _SBF(f,v) is intended to be used in "OR" and "AND" expressions: + * e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)" + */ +#undef _SBF +/* Set bit field macro */ +#define _SBF(f, v) ((v) << (f)) + +/* _BITMASK constructs a symbol with 'field_width' least significant + * bits set. + * e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF + * The symbol is intended to be used to limit the bit field width + * thusly: + * = (any_expression) & _BITMASK(x), where 0 < x <= 32. + * If "any_expression" results in a value that is larger than can be + * contained in 'x' bits, the bits above 'x - 1' are masked off. When + * used with the _SBF example above, the example would be written: + * a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16)) + * This ensures that the value written to a_reg is no wider than + * 16 bits, and makes the code easier to read and understand. + */ +#undef _BITMASK +/* Bitmask creation macro */ +#define _BITMASK(field_width) ( _BIT(field_width) - 1) + +/* NULL pointer */ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +/* Number of elements in an array */ +#define NELEMENTS(array) (sizeof(array) / sizeof(array[0])) + +/* Static data/function define */ +#define STATIC static +/* External data/function define */ +#define EXTERN extern + +#if !defined(MAX) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +#if !defined(MIN) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +/** + * @} + */ + +/* Old Type Definition compatibility */ +/** @addtogroup LPC_Types_Public_Types + * @{ + */ + +/** LPC type for character type */ +typedef char CHAR; + +/** LPC type for 8 bit unsigned value */ +typedef uint8_t UNS_8; + +/** LPC type for 8 bit signed value */ +typedef int8_t INT_8; + +/** LPC type for 16 bit unsigned value */ +typedef uint16_t UNS_16; + +/** LPC type for 16 bit signed value */ +typedef int16_t INT_16; + +/** LPC type for 32 bit unsigned value */ +typedef uint32_t UNS_32; + +/** LPC type for 32 bit signed value */ +typedef int32_t INT_32; + +/** LPC type for 64 bit signed value */ +typedef int64_t INT_64; + +/** LPC type for 64 bit unsigned value */ +typedef uint64_t UNS_64; + +#ifdef __CODE_RED +#define BOOL_32 bool +#define BOOL_16 bool +#define BOOL_8 bool +#else +/** 32 bit boolean type */ +typedef bool BOOL_32; + +/** 16 bit boolean type */ +typedef bool BOOL_16; + +/** 8 bit boolean type */ +typedef bool BOOL_8; +#endif + +#ifdef __CC_ARM +#define INLINE __inline +#else +#define INLINE inline +#endif + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __LPC_TYPES_H_ */ diff --git a/lpc_chip_15xx/inc/mrt_15xx.h b/lpc_chip_15xx/inc/mrt_15xx.h new file mode 100644 index 0000000..f153dc4 --- /dev/null +++ b/lpc_chip_15xx/inc/mrt_15xx.h @@ -0,0 +1,339 @@ +/* + * @brief LPC15xx Multi-Rate Timer (MRT) registers and driver functions + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __MRT_15XX_H_ +#define __MRT_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup MRT_15XX CHIP: LPC15xx Multi-Rate Timer driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15xx MRT chip configuration + */ +#define MRT_CHANNELS_NUM (4) +#define MRT_NO_IDLE_CHANNEL (0x40) + +/** + * @brief MRT register block structure + */ +typedef struct { + __IO uint32_t INTVAL; /*!< Timer interval register */ + __O uint32_t TIMER; /*!< Timer register */ + __IO uint32_t CTRL; /*!< Timer control register */ + __IO uint32_t STAT; /*!< Timer status register */ +} LPC_MRT_CH_T; + +/** + * @brief MRT register block structure + */ +typedef struct { + LPC_MRT_CH_T CHANNEL[MRT_CHANNELS_NUM]; + uint32_t unused[45]; + __O uint32_t IDLE_CH; + __IO uint32_t IRQ_FLAG; +} LPC_MRT_T; + +/** + * @brief MRT Interrupt Modes enum + */ +typedef enum MRT_MODE { + MRT_MODE_REPEAT = (0 << 1), /*!< MRT Repeat interrupt mode */ + MRT_MODE_ONESHOT = (1 << 1) /*!< MRT One-shot interrupt mode */ +} MRT_MODE_T; + +/** + * @brief MRT register bit fields & masks + */ +/* MRT Time interval register bit fields */ +#define MRT_INTVAL_IVALUE (0x00FFFFFF) /* Maximum interval load value and mask */ +#define MRT_INTVAL_LOAD (0x80000000UL) /* Force immediate load of timer interval register bit */ + +/* MRT Control register bit fields & masks */ +#define MRT_CTRL_INTEN_MASK (0x01) +#define MRT_CTRL_MODE_MASK (0x06) + +/* MRT Status register bit fields & masks */ +#define MRT_STAT_INTFLAG (0x01) +#define MRT_STAT_RUNNING (0x02) + +/* Pointer to individual MR register blocks */ +#define LPC_MRT_CH0 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[0]) +#define LPC_MRT_CH1 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[1]) +#define LPC_MRT_CH2 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[2]) +#define LPC_MRT_CH3 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[3]) +#define LPC_MRT_CH(ch) ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[(ch)]) + +/* Global interrupt flag register interrupt mask/clear values */ +#define MRT0_INTFLAG (1) +#define MRT1_INTFLAG (2) +#define MRT2_INTFLAG (4) +#define MRT3_INTFLAG (8) +#define MRTn_INTFLAG(ch) (1 << (ch)) + +/** + * @brief Initializes the MRT + * @return Nothing + */ +STATIC INLINE void Chip_MRT_Init(void) +{ + /* Enable the clock to the register interface */ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT); + + /* Reset MRT */ + Chip_SYSCTL_PeriphReset(RESET_MRT); +} + +/** + * @brief De-initializes the MRT Channel + * @return Nothing + */ +STATIC INLINE void Chip_MRT_DeInit(void) +{ + /* Disable the clock to the MRT */ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MRT); +} + +/** + * @brief Returns a pointer to the register block for a MRT channel + * @param ch : MRT channel tog et register block for (0..3) + * @return Pointer to the MRT register block for the channel + */ +STATIC INLINE LPC_MRT_CH_T *Chip_MRT_GetRegPtr(uint8_t ch) +{ + return LPC_MRT_CH(ch); +} + +/** + * @brief Returns the timer time interval value + * @param pMRT : Pointer to selected MRT Channel + * @return Timer time interval value (IVALUE) + */ +STATIC INLINE uint32_t Chip_MRT_GetInterval(LPC_MRT_CH_T *pMRT) +{ + return pMRT->INTVAL; +} + +/** + * @brief Sets the timer time interval value + * @param pMRT : Pointer to selected MRT Channel + * @param interval : The interval timeout (31-bits) + * @return Nothing + * @note Setting bit 31 in timer time interval register causes the time interval value + * to load immediately, otherwise the time interval value will be loaded in + * next timer cycle.
+ * Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately
+ * Example: Chip_MRT_SetInterval(pMRT, 0x500); // Will load timer interval after internal expires + */ +STATIC INLINE void Chip_MRT_SetInterval(LPC_MRT_CH_T *pMRT, uint32_t interval) +{ + pMRT->INTVAL = interval; +} + +/** + * @brief Returns the current timer value + * @param pMRT : Pointer to selected MRT Channel + * @return The current timer value + */ +STATIC INLINE uint32_t Chip_MRT_GetTimer(LPC_MRT_CH_T *pMRT) +{ + return pMRT->TIMER; +} + +/** + * @brief Returns true if the timer is enabled + * @param pMRT : Pointer to selected MRT Channel + * @return True if enabled, Flase if not enabled + */ +STATIC INLINE bool Chip_MRT_GetEnabled(LPC_MRT_CH_T *pMRT) +{ + return (bool) ((pMRT->CTRL & MRT_CTRL_INTEN_MASK) != 0); +} + +/** + * @brief Enables the timer + * @param pMRT : Pointer to selected MRT Channel + * @return Nothing + */ +STATIC INLINE void Chip_MRT_SetEnabled(LPC_MRT_CH_T *pMRT) +{ + pMRT->CTRL |= MRT_CTRL_INTEN_MASK; +} + +/** + * @brief Disables the timer + * @param pMRT : Pointer to selected MRT Channel + * @return Nothing + */ +STATIC INLINE void Chip_MRT_SetDisabled(LPC_MRT_CH_T *pMRT) +{ + pMRT->CTRL &= ~MRT_CTRL_INTEN_MASK; +} + +/** + * @brief Returns the timer mode (repeat or one-shot) + * @param pMRT : Pointer to selected MRT Channel + * @return The current timer mode + */ +STATIC INLINE MRT_MODE_T Chip_MRT_GetMode(LPC_MRT_CH_T *pMRT) +{ + return (MRT_MODE_T) (pMRT->CTRL & MRT_CTRL_MODE_MASK); +} + +/** + * @brief Sets the timer mode (repeat or one-shot) + * @param pMRT : Pointer to selected MRT Channel + * @param mode : Timer mode + * @return Nothing + */ +STATIC INLINE void Chip_MRT_SetMode(LPC_MRT_CH_T *pMRT, MRT_MODE_T mode) +{ + uint32_t reg; + + reg = pMRT->CTRL & ~MRT_CTRL_MODE_MASK; + pMRT->CTRL = reg | (uint32_t) mode; +} + +/** + * @brief Check if the timer is configured in repeat mode + * @param pMRT : Pointer to selected MRT Channel + * @return True if in repeat mode, False if in one-shot mode + */ +STATIC INLINE bool Chip_MRT_IsRepeatMode(LPC_MRT_CH_T *pMRT) +{ + return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? false : true; +} + +/** + * @brief Check if the timer is configured in one-shot mode + * @param pMRT : Pointer to selected MRT Channel + * @return True if in one-shot mode, False if in repeat mode + */ +STATIC INLINE bool Chip_MRT_IsOneShotMode(LPC_MRT_CH_T *pMRT) +{ + return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? true : false; +} + +/** + * @brief Check if the timer has an interrupt pending + * @param pMRT : Pointer to selected MRT Channel + * @return True if interrupt is pending, False if no interrupt is pending + */ +STATIC INLINE bool Chip_MRT_IntPending(LPC_MRT_CH_T *pMRT) +{ + return (bool) ((pMRT->STAT & MRT_STAT_INTFLAG) != 0); +} + +/** + * @brief Clears the pending interrupt (if any) + * @param pMRT : Pointer to selected MRT Channel + * @return Nothing + */ +STATIC INLINE void Chip_MRT_IntClear(LPC_MRT_CH_T *pMRT) +{ + pMRT->STAT |= MRT_STAT_INTFLAG; +} + +/** + * @brief Check if the timer is running + * @param pMRT : Pointer to selected MRT Channel + * @return True if running, False if stopped + */ +STATIC INLINE bool Chip_MRT_Running(LPC_MRT_CH_T *pMRT) +{ + return (bool) ((pMRT->STAT & MRT_STAT_RUNNING) != 0); +} + +/** + * @brief Returns the IDLE channel value + * @return IDLE channel value (unshifted in bits 7..4) + */ +STATIC INLINE uint8_t Chip_MRT_GetIdleChannel(void) +{ + return (uint8_t) (LPC_MRT->IDLE_CH); +} + +/** + * @brief Returns the IDLE channel value + * @return IDLE channel value (shifted in bits 3..0) + */ +STATIC INLINE uint8_t Chip_MRT_GetIdleChannelShifted(void) +{ + return (uint8_t) (Chip_MRT_GetIdleChannel() >> 4); +} + +/** + * @brief Returns the interrupt pending status for all MRT channels + * @return IRQ pending channel bitfield(bit 0 = MRT0, bit 1 = MRT1, etc.) + */ +STATIC INLINE uint32_t Chip_MRT_GetIntPending(void) +{ + return LPC_MRT->IRQ_FLAG; +} + +/** + * @brief Returns the interrupt pending status for a singel MRT channel + * @param ch : Channel to check pending interrupt status for + * @return IRQ pending channel number + */ +STATIC INLINE bool Chip_MRT_GetIntPendingByChannel(uint8_t ch) +{ + return (bool) (((LPC_MRT->IRQ_FLAG >> ch) & 1) != 0); +} + +/** + * @brief Clears the interrupt pending status for one or more MRT channels + * @param mask : Channels to clear (bit 0 = MRT0, bit 1 = MRT1, etc.) + * @return Nothing + * @note Use this function to clear multiple interrupt pending states in + * a single call via the IRQ_FLAG register. Performs the same function for + * all MRT channels in a single call as the Chip_MRT_IntClear() does for a + * single channel. + */ +STATIC INLINE void Chip_MRT_ClearIntPending(uint32_t mask) +{ + LPC_MRT->IRQ_FLAG = mask; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MRT_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/pinint_15xx.h b/lpc_chip_15xx/inc/pinint_15xx.h new file mode 100644 index 0000000..842c9fc --- /dev/null +++ b/lpc_chip_15xx/inc/pinint_15xx.h @@ -0,0 +1,258 @@ +/* + * @brief LPC15xx Pin Interrupt and Pattern Match Registers and driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __PININT_15XX_H_ +#define __PININT_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PININT_15XX CHIP: LPC15xx Pin Interrupt driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15xx Pin Interrupt and Pattern Match register block structure + */ +typedef struct { /*!< PIN_INT Structure */ + __IO uint32_t ISEL; /*!< Pin Interrupt Mode register */ + __IO uint32_t IENR; /*!< Pin Interrupt Enable (Rising) register */ + __IO uint32_t SIENR; /*!< Set Pin Interrupt Enable (Rising) register */ + __IO uint32_t CIENR; /*!< Clear Pin Interrupt Enable (Rising) register */ + __IO uint32_t IENF; /*!< Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t SIENF; /*!< Set Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t CIENF; /*!< Clear Pin Interrupt Enable Falling Edge / Active Level address */ + __IO uint32_t RISE; /*!< Pin Interrupt Rising Edge register */ + __IO uint32_t FALL; /*!< Pin Interrupt Falling Edge register */ + __IO uint32_t IST; /*!< Pin Interrupt Status register */ +} LPC_PIN_INT_T; + +/** + * LPC15xx Pin Interrupt channel values + */ +#define PININTCH0 (1 << 0) +#define PININTCH1 (1 << 1) +#define PININTCH2 (1 << 2) +#define PININTCH3 (1 << 3) +#define PININTCH4 (1 << 4) +#define PININTCH5 (1 << 5) +#define PININTCH6 (1 << 6) +#define PININTCH7 (1 << 7) +#define PININTCH(ch) (1 << (ch)) + +/** + * @brief Initialize Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @return Nothing + * @note This function should be used after the Chip_GPIO_Init() function. + */ +STATIC INLINE void Chip_PININT_Init(LPC_PIN_INT_T *pPININT) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_PININT); + Chip_SYSCTL_PeriphReset(RESET_PININT); +} + +/** + * @brief De-Initialize Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @return Nothing + */ +STATIC INLINE void Chip_PININT_DeInit(LPC_PIN_INT_T *pPININT) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_PININT); +} + +/** + * @brief Configure the pins as edge sensitive in Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_SetPinModeEdge(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->ISEL &= ~pins; +} + +/** + * @brief Configure the pins as level sensitive in Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_SetPinModeLevel(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->ISEL |= pins; +} + +/** + * @brief Return current PININT rising edge or high level interrupt enable state + * @param pPININT : The base address of Pin interrupt block + * @return A bifield containing the high edge/level interrupt enables for each + * interrupt. Bit 0 = PININT0, 1 = PININT1, etc. + * For each bit, a 0 means the high edge/level interrupt is disabled, while a 1 + * means it's enabled. + */ +STATIC INLINE uint32_t Chip_PININT_GetHighEnabled(LPC_PIN_INT_T *pPININT) +{ + return pPININT->IENR; +} + +/** + * @brief Enable high edge/level PININT interrupts for pins + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins to enable (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_EnableIntHigh(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->SIENR = pins; +} + +/** + * @brief Disable high edge/level PININT interrupts for pins + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins to disable (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_DisableIntHigh(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->CIENR = pins; +} + +/** + * @brief Return current PININT falling edge or low level interrupt enable state + * @param pPININT : The base address of Pin interrupt block + * @return A bifield containing the low edge/level interrupt enables for each + * interrupt. Bit 0 = PININT0, 1 = PININT1, etc. + * For each bit, a 0 means the low edge/level interrupt is disabled, while a 1 + * means it's enabled. + */ +STATIC INLINE uint32_t Chip_PININT_GetLowEnabled(LPC_PIN_INT_T *pPININT) +{ + return pPININT->IENF; +} + +/** + * @brief Enable low edge/level PININT interrupts for pins + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins to enable (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_EnableIntLow(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->SIENF = pins; +} + +/** + * @brief Disable low edge/level PININT interrupts for pins + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins to disable (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_DisableIntLow(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->CIENF = pins; +} + +/** + * @brief Return pin states that have a detected latched high edge (RISE) state + * @param pPININT : The base address of Pin interrupt block + * @return PININT states (bit n = high) with a latched rise state detected + */ +STATIC INLINE uint32_t Chip_PININT_GetRiseStates(LPC_PIN_INT_T *pPININT) +{ + return pPININT->RISE; +} + +/** + * @brief Clears pin states that had a latched high edge (RISE) state + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins with latched states to clear + * @return Nothing + */ +STATIC INLINE void Chip_PININT_ClearRiseStates(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->RISE = pins; +} + +/** + * @brief Return pin states that have a detected latched falling edge (FALL) state + * @param pPININT : The base address of Pin interrupt block + * @return PININT states (bit n = high) with a latched rise state detected + */ +STATIC INLINE uint32_t Chip_PININT_GetFallStates(LPC_PIN_INT_T *pPININT) +{ + return pPININT->FALL; +} + +/** + * @brief Clears pin states that had a latched falling edge (FALL) state + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pins with latched states to clear + * @return Nothing + */ +STATIC INLINE void Chip_PININT_ClearFallStates(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->FALL = pins; +} + +/** + * @brief Get interrupt status from Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @return Interrupt status (bit n for PININTn = high means interrupt ie pending) + */ +STATIC INLINE uint32_t Chip_PININT_GetIntStatus(LPC_PIN_INT_T *pPININT) +{ + return pPININT->IST; +} + +/** + * @brief Clear interrupt status in Pin interrupt block + * @param pPININT : The base address of Pin interrupt block + * @param pins : Pin interrupts to clear (ORed value of PININTCH*) + * @return Nothing + */ +STATIC INLINE void Chip_PININT_ClearIntStatus(LPC_PIN_INT_T *pPININT, uint32_t pins) +{ + pPININT->IST = pins; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PININT_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/pmu_15xx.h b/lpc_chip_15xx/inc/pmu_15xx.h new file mode 100644 index 0000000..d68ba2f --- /dev/null +++ b/lpc_chip_15xx/inc/pmu_15xx.h @@ -0,0 +1,285 @@ +/* + * @brief LPC15xx PMU chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __PMU_15XX_H_ +#define __PMU_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PMU_15XX CHIP: LPC15xx PMU driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15xx Power Management Unit register block structure + */ +typedef struct { + __IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */ + __IO uint32_t GPREG[5]; /*!< Offset: 0x004 General purpose Registers 0..4 (R/W) */ +} LPC_PMU_T; + +/** + * @brief LPC15xx low power mode type definitions + */ +typedef enum CHIP_PMU_MCUPOWER { + PMU_MCU_SLEEP = 0, /*!< Sleep mode */ + PMU_MCU_DEEP_SLEEP, /*!< Deep Sleep mode */ + PMU_MCU_POWER_DOWN, /*!< Power down mode */ + PMU_MCU_DEEP_PWRDOWN /*!< Deep power down mode */ +} CHIP_PMU_MCUPOWER_T; + +/** + * PMU PCON register bit fields & masks + */ +#define PMU_PCON_PM_DEEPPOWERDOWN (0x1) /*!< ARM WFI enter Deep Power-down mode */ +#define PMU_PCON_NODPD (1 << 3) /*!< Disable deep power-down mode */ +#define PMU_PCON_SLEEPFLAG (1 << 8) /*!< Sleep mode flag */ +#define PMU_PCON_DPDFLAG (1 << 11) /*!< Deep power-down flag */ + +/** + * PMU GPREG[4] register bit fields & masks + */ +#define PMU_GPREG4_WAKEUPHYS (1 << 0) /** Enable wake-up pin hysteresis */ +#define PMU_GPREG4_WAKEPAD_DISABLE (1 << 1) /** Disable the Wake-up */ +#define PMU_GPREG4_DATA ((uint32_t) 0x3fffff << 10) /** GP register 4 data field */ + +/** + * @brief Write a value to a GPREG register + * @param pPMU : Pointer to PMU register block + * @param regIndex : Register index to write to, must be 0..3 + * @param value : Value to write + * @return None + */ +STATIC INLINE void Chip_PMU_WriteGPREG(LPC_PMU_T *pPMU, uint8_t regIndex, uint32_t value) +{ + pPMU->GPREG[regIndex] = value; +} + +/** + * @brief Write data to GPREG4 register + * @param pPMU : Pointer to PMU register block + * @param value : Data to be written to GPREG4 + * @return None + */ +STATIC INLINE void Chip_PMU_WriteGPREG4(LPC_PMU_T *pPMU, uint32_t value) +{ + uint32_t reg; + + reg = pPMU->GPREG[4] & ~PMU_GPREG4_DATA; + pPMU->GPREG[4] = reg | (value << 10); +} + +/** + * @brief Read a value to a GPREG register + * @param pPMU : Pointer to PMU register block + * @param regIndex : Register index to read from, must be 0..3 + * @return Value read from the GPREG register + */ +STATIC INLINE uint32_t Chip_PMU_ReadGPREG(LPC_PMU_T *pPMU, uint8_t regIndex) +{ + return pPMU->GPREG[regIndex]; +} + +/** + * @brief Enter MCU Sleep mode + * @param pPMU : Pointer to PMU register block + * @return None + * @note The sleep mode affects the ARM Cortex-M0+ core only. Peripherals + * and memories are active. + */ +void Chip_PMU_SleepState(LPC_PMU_T *pPMU); + +/** + * @brief Enter MCU Deep Sleep mode + * @param pPMU : Pointer to PMU register block + * @return None + * @note In Deep-sleep mode, the peripherals receive no internal clocks. + * The flash is in stand-by mode. The SRAM memory and all peripheral registers + * as well as the processor maintain their internal states. The WWDT, WKT, + * and BOD can remain active to wake up the system on an interrupt. + */ +void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU); + +/** + * @brief Enter MCU Power down mode + * @param pPMU : Pointer to PMU register block + * @return None + * @note In Power-down mode, the peripherals receive no internal clocks. + * The internal SRAM memory and all peripheral registers as well as the + * processor maintain their internal states. The flash memory is powered + * down. The WWDT, WKT, and BOD can remain active to wake up the system + * on an interrupt. + */ +void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU); + +/** + * @brief Enter MCU Deep Power down mode + * @param pPMU : Pointer to PMU register block + * @return None + * @note For maximal power savings, the entire system is shut down + * except for the general purpose registers in the PMU and the self + * wake-up timer. Only the general purpose registers in the PMU maintain + * their internal states. The part can wake up on a pulse on the WAKEUP + * pin or when the self wake-up timer times out. On wake-up, the part + * reboots. + */ +void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU); + +/** + * @brief Place the MCU in a low power state + * @param pPMU : Pointer to PMU register block + * @param SleepMode : Sleep mode + * @return None + */ +void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode); + +/** + * @brief Disables deep power-down mode + * @param pPMU : Pointer to PMU register block + * @return None + * @note Calling this functions prevents entry to Deep power-down + * mode. Once set, this can only be cleared by power-on reset. + */ +STATIC INLINE void Chip_PMU_DisableDeepPowerDown(LPC_PMU_T *pPMU) +{ + pPMU->PCON |= PMU_PCON_NODPD; +} + +/** + * @brief Returns sleep/power-down flags + * @param pPMU : Pointer to PMU register block + * @return Or'ed values of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG + * @note These indicate that the PMU is setup for entry into a low + * power state on the next WFI() instruction. + */ +STATIC INLINE uint32_t Chip_PMU_GetSleepFlags(LPC_PMU_T *pPMU) +{ + return pPMU->PCON & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG); +} + +/** + * @brief Clears sleep/power-down flags + * @param pPMU : Pointer to PMU register block + * @param flags : Or'ed value of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG + * @return Nothing + * @note Use this function to clear a low power state prior to calling + * WFI(). + */ +STATIC INLINE void Chip_PMU_ClearSleepFlags(LPC_PMU_T *pPMU, uint32_t flags) +{ + pPMU->PCON |= (flags & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG)); +} + +/** + * @brief Returns Wakeup Hysterisis enable flag + * @param pPMU : Pointer to PMU register block + * @return TRUE if bit PMU_GPREG4_WAKEUPHYS is set else returns FALSE + * @note This indicate that whether wakeup hysterisis + * is enabled or not. + */ +STATIC INLINE bool Chip_PMU_GetWakeHysEnable(LPC_PMU_T *pPMU) +{ + return (pPMU->GPREG[4] & PMU_GPREG4_WAKEUPHYS) != 0; +} + +/** + * @brief Sets Wakeup Hysterisis enable flag + * @param pPMU : Pointer to PMU register block + * @return Nothing + * @note Use this function to prevent enable wakeup hysterisis + * note that if Vcc goes below 2.2V then it might prevent wakeup + * if hysterisis is enabled + */ +STATIC INLINE void Chip_PMU_SetWakeHysEnable(LPC_PMU_T *pPMU) +{ + pPMU->GPREG[4] |= PMU_GPREG4_WAKEUPHYS; +} + +/** + * @brief Clears Wakeup Hysterisis enable flag + * @param pPMU : Pointer to PMU register block + * @return Nothing + * @note Use this function to disable wakeup hysterisis + */ +STATIC INLINE void Chip_PMU_ClearWakeHysEnable(LPC_PMU_T *pPMU) +{ + pPMU->GPREG[4] &= ~PMU_GPREG4_WAKEUPHYS; +} + +/** + * @brief Returns Wakeup Pad disable bit + * @param pPMU : Pointer to PMU register block + * @return TRUE if bit PMU_GPREG4_WAKEPAD_DISABLE is set else returns FALSE + * @note This indicate that whether wakeup hysterisis + * is enabled or not. + */ +STATIC INLINE bool Chip_PMU_GetWakePadDisable(LPC_PMU_T *pPMU) +{ + return (pPMU->GPREG[4] & PMU_GPREG4_WAKEPAD_DISABLE) != 0; +} + +/** + * @brief Sets Wakeup pad disable bit + * @param pPMU : Pointer to PMU register block + * @return Nothing + * @note Use this function to disable the wakeup pin (P0.17) + * in which case RTC wakeup is the only option to wakeup from + * deep power down mode. + */ +STATIC INLINE void Chip_PMU_SetWakePadDisable(LPC_PMU_T *pPMU) +{ + pPMU->GPREG[4] |= PMU_GPREG4_WAKEPAD_DISABLE; +} + +/** + * @brief Clears Wakeup pad disable bit + * @param pPMU : Pointer to PMU register block + * @return Nothing + * @note Use this function to enable the wakeup pin (P0.17) + * to wakeup from deep power down mode. + */ +STATIC INLINE void Chip_PMU_ClearWakePadDisable(LPC_PMU_T *pPMU) +{ + pPMU->GPREG[4] &= ~PMU_GPREG4_WAKEPAD_DISABLE; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PMU_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/ring_buffer.h b/lpc_chip_15xx/inc/ring_buffer.h new file mode 100644 index 0000000..30412d9 --- /dev/null +++ b/lpc_chip_15xx/inc/ring_buffer.h @@ -0,0 +1,188 @@ +/* + * @brief Common ring buffer support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __RING_BUFFER_H_ +#define __RING_BUFFER_H_ + +#include "lpc_types.h" + +/** @defgroup Ring_Buffer CHIP: Simple ring buffer implementation + * @ingroup CHIP_Common + * @{ + */ + +/** + * @brief Ring buffer structure + */ +typedef struct { + void *data; + int count; + int itemSz; + uint32_t head; + uint32_t tail; +} RINGBUFF_T; + +/** + * @def RB_VHEAD(rb) + * volatile typecasted head index + */ +#define RB_VHEAD(rb) (*(volatile uint32_t *) &(rb)->head) + +/** + * @def RB_VTAIL(rb) + * volatile typecasted tail index + */ +#define RB_VTAIL(rb) (*(volatile uint32_t *) &(rb)->tail) + +/** + * @brief Initialize ring buffer + * @param RingBuff : Pointer to ring buffer to initialize + * @param buffer : Pointer to buffer to associate with RingBuff + * @param itemSize : Size of each buffer item size + * @param count : Size of ring buffer + * @note Memory pointed by @a buffer must have correct alignment of + * @a itemSize, and @a count must be a power of 2 and must at + * least be 2 or greater. + * @return Nothing + */ +int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count); + +/** + * @brief Resets the ring buffer to empty + * @param RingBuff : Pointer to ring buffer + * @return Nothing + */ +STATIC INLINE void RingBuffer_Flush(RINGBUFF_T *RingBuff) +{ + RingBuff->head = RingBuff->tail = 0; +} + +/** + * @brief Return size the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Size of the ring buffer in bytes + */ +STATIC INLINE int RingBuffer_GetSize(RINGBUFF_T *RingBuff) +{ + return RingBuff->count; +} + +/** + * @brief Return number of items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Number of items in the ring buffer + */ +STATIC INLINE int RingBuffer_GetCount(RINGBUFF_T *RingBuff) +{ + return RB_VHEAD(RingBuff) - RB_VTAIL(RingBuff); +} + +/** + * @brief Return number of free items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return Number of free items in the ring buffer + */ +STATIC INLINE int RingBuffer_GetFree(RINGBUFF_T *RingBuff) +{ + return RingBuff->count - RingBuffer_GetCount(RingBuff); +} + +/** + * @brief Return number of items in the ring buffer + * @param RingBuff : Pointer to ring buffer + * @return 1 if the ring buffer is full, otherwise 0 + */ +STATIC INLINE int RingBuffer_IsFull(RINGBUFF_T *RingBuff) +{ + return (RingBuffer_GetCount(RingBuff) >= RingBuff->count); +} + +/** + * @brief Return empty status of ring buffer + * @param RingBuff : Pointer to ring buffer + * @return 1 if the ring buffer is empty, otherwise 0 + */ +STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff) +{ + return RB_VHEAD(RingBuff) == RB_VTAIL(RingBuff); +} + +/** + * @brief Insert a single item into ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : pointer to item + * @return 1 when successfully inserted, + * 0 on error (Buffer not initialized using + * RingBuffer_Init() or attempted to insert + * when buffer is full) + */ +int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data); + +/** + * @brief Insert an array of items into ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to first element of the item array + * @param num : Number of items in the array + * @return number of items successfully inserted, + * 0 on error (Buffer not initialized using + * RingBuffer_Init() or attempted to insert + * when buffer is full) + */ +int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num); + +/** + * @brief Pop an item from the ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to memory where popped item be stored + * @return 1 when item popped successfuly onto @a data, + * 0 When error (Buffer not initialized using + * RingBuffer_Init() or attempted to pop item when + * the buffer is empty) + */ +int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data); + +/** + * @brief Pop an array of items from the ring buffer + * @param RingBuff : Pointer to ring buffer + * @param data : Pointer to memory where popped items be stored + * @param num : Max number of items array @a data can hold + * @return Number of items popped onto @a data, + * 0 on error (Buffer not initialized using RingBuffer_Init() + * or attempted to pop when the buffer is empty) + */ +int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num); + + +/** + * @} + */ + +#endif /* __RING_BUFFER_H_ */ diff --git a/lpc_chip_15xx/inc/ritimer_15xx.h b/lpc_chip_15xx/inc/ritimer_15xx.h new file mode 100644 index 0000000..ac5dd11 --- /dev/null +++ b/lpc_chip_15xx/inc/ritimer_15xx.h @@ -0,0 +1,265 @@ +/* + * @brief LPC15xx RITimer driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __RITIMER_15XX_H_ +#define __RITIMER_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup RIT_15XX CHIP: LPC15xx Repetitive Interrupt Timer driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief Repetitive Interrupt Timer register block structure + */ +typedef struct { /*!< RITIMER Structure */ + __IO uint32_t COMPVAL; /*!< Compare register */ + __IO uint32_t MASK; /*!< Mask register. This register holds the 32-bit mask value. A 1 written to any bit will force a compare on the corresponding bit of the counter and compare register. */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t COUNTER; /*!< 32-bit counter */ + __IO uint32_t COMPVAL_H; /*!< Compare upper register */ + __IO uint32_t MASK_H; /*!< Mask upper register */ + __I uint32_t RESERVED0[1]; + __IO uint32_t COUNTER_H; /*!< Counter upper register */ +} LPC_RITIMER_T; + +/* + * RIT control register + */ +/** Set by H/W when the counter value equals the masked compare value */ +#define RIT_CTRL_INT (1 << 0) +/** Set timer enable clear to 0 when the counter value equals the masked compare value */ +#define RIT_CTRL_ENCLR (1 << 1) +/** Set timer enable on debug */ +#define RIT_CTRL_ENBR (1 << 2) +/** Set timer enable */ +#define RIT_CTRL_TEN (1 << 3) + +/** + * @brief Initialize the RIT + * @param pRITimer : RITimer peripheral selected + * @return None + * @note The timer will not br running after this call. Use + * Chip_RIT_Enable() to start the timer running. + */ +void Chip_RIT_Init(LPC_RITIMER_T *pRITimer); + +/** + * @brief Shutdown the RIT + * @param pRITimer : RITimer peripheral selected + * @return None + */ +void Chip_RIT_DeInit(LPC_RITIMER_T *pRITimer); + +/** + * @brief Safely sets CTRL register bits + * @param pRITimer : RITimer peripheral selected + * @param val : RIT bits to be set, one or more RIT_CTRL_* values + * @return None + */ +void Chip_RIT_SetCTRL(LPC_RITIMER_T *pRITimer, uint32_t val); + +/** + * @brief Safely clears CTRL register bits + * @param pRITimer : RITimer peripheral selected + * @param val : RIT bits to be cleared, one or more RIT_CTRL_* values + * @return None + */ +void Chip_RIT_ClearCTRL(LPC_RITIMER_T *pRITimer, uint32_t val); + +/** + * @brief Enable Timer + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_Enable(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_SetCTRL(pRITimer, RIT_CTRL_TEN); +} + +/** + * @brief Disable Timer + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_Disable(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_ClearCTRL(pRITimer, RIT_CTRL_TEN); +} + +/** + * @brief Enable timer debug mode + * @param pRITimer : RITimer peripheral selected + * @return None + * @note This function halts the repetitive timer when + * the processor is halted for debugging. + */ +STATIC INLINE void Chip_RIT_EnableDebug(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_SetCTRL(pRITimer, RIT_CTRL_ENBR); +} + +/** + * @brief Disable timer debug mode + * @param pRITimer : RITimer peripheral selected + * @return None + * @note This function allows the repetitive timer to continue running + * when the processor is halted for debugging. + */ +STATIC INLINE void Chip_RIT_DisableDebug(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_ClearCTRL(pRITimer, RIT_CTRL_ENBR); +} + +/** + * @brief Enables automatic counter clear on compare + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_EnableCompClear(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_SetCTRL(pRITimer, RIT_CTRL_ENCLR); +} + +/** + * @brief Disables automatic counter clear on compare + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_DisableCompClear(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_ClearCTRL(pRITimer, RIT_CTRL_ENCLR); +} + +/** + * @brief Check whether timer interrupt is pending + * @param pRITimer : RITimer peripheral selected + * @return true if the interrupt is pending, otherwise false + */ +STATIC INLINE bool Chip_RIT_GetIntStatus(LPC_RITIMER_T *pRITimer) +{ + return (bool) ((pRITimer->CTRL & RIT_CTRL_INT) != 0); +} + +/** + * @brief Clears the timer interrupt pending state + * @param pRITimer : RITimer peripheral selected + * @return None + */ +STATIC INLINE void Chip_RIT_ClearIntStatus(LPC_RITIMER_T *pRITimer) +{ + Chip_RIT_SetCTRL(pRITimer, RIT_CTRL_INT); +} + +/** + * @brief Set a tick value for the interrupt to time out + * @param pRITimer : RITimer peripheral selected + * @param val : value (in ticks) for the coounter compare value + * @return None + * @note The base timer tick rate can be determined by calling + * Chip_Clock_GetSystemClockRate(). + */ +void Chip_RIT_SetCompareValue(LPC_RITIMER_T *pRITimer, uint64_t val); + +/** + * @brief Returns the current timer compare value + * @param pRITimer : RITimer peripheral selected + * @return the current timer compare value + */ +uint64_t Chip_RIT_GetCompareValue(LPC_RITIMER_T *pRITimer); + +/** + * @brief Sets a mask value used for bit based compare + * @param pRITimer : RITimer peripheral selected + * @param mask : Mask value for timer (see user manual) + * @return None + */ +void Chip_RIT_SetMaskValue(LPC_RITIMER_T *pRITimer, uint64_t mask); + +/** + * @brief Returns the mask value used for bit based compare + * @param pRITimer : RITimer peripheral selected + * @return the current mask value + */ +uint64_t Chip_RIT_GetMaskValue(LPC_RITIMER_T *pRITimer); + +/** + * @brief Sets the current timer Counter value + * @param pRITimer : RITimer peripheral selected + * @param count : Count value to set timer to + * @return Nothing + */ +void Chip_RIT_SetCounter(LPC_RITIMER_T *pRITimer, uint64_t count); + +/** + * @brief Returns the current timer Counter value + * @param pRITimer : RITimer peripheral selected + * @return the current timer counter value + */ +uint64_t Chip_RIT_GetCounter(LPC_RITIMER_T *pRITimer); + +/** + * @brief Set timer interval value in Hz (frequency) + * @param pRITimer : RITimer peripheral selected + * @param freq : timer interval value in Hz + * @return None + * @note Will not alter current counter value. Accuracy depends on + * base clock rate. Timer enable/disable state is not changed. + */ +void Chip_RIT_SetTimerIntervalHz(LPC_RITIMER_T *pRITimer, uint32_t freq); + +/** + * @brief Returns base clock rate for timer + * @param pRITimer : RITimer peripheral selected + * @return Value in Hz the timer is running at + * @note This returned value contains the base clock the timer uses. + * If you set the tick count to this return value with the + * Chip_RIT_SetCompareValue() function, you will get a 1Hz + * interval rate. + */ +STATIC INLINE uint32_t Chip_RIT_GetBaseClock(LPC_RITIMER_T *pRITimer) +{ + return Chip_Clock_GetSystemClockRate(); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RITIMER_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_adc_15xx.h b/lpc_chip_15xx/inc/rom_adc_15xx.h new file mode 100644 index 0000000..7cfd30d --- /dev/null +++ b/lpc_chip_15xx/inc/rom_adc_15xx.h @@ -0,0 +1,152 @@ +/* + * @brief LPC15xx ROM ADC API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_ADC_15XX_H_ +#define __ROM_ADC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ADCROM_15XX CHIP: LPC15xx ADC ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/** + * @brief ADC handle type + */ +typedef void *ADC_HANDLE_T; + +typedef void (*ADC_SEQ_CALLBK_T)(ADC_HANDLE_T handle); +typedef void (*ADC_CALLBK_T)(ErrorCode_t error_code, uint32_t num_channel); + +/* Typedef for structure pointed by the ADC_HANDLE */ +typedef struct { /* block of RAM allocated by the application program */ + uint32_t base_addr; /* adcr register base address */ + uint32_t *seqa_buffer; /* adc buffer */ + uint32_t *seqb_buffer; /* adc buffer */ + uint32_t seqa_channel_num; /* number of ADC channels */ + uint32_t seqb_channel_num; /* number of ADC channels */ + uint32_t seqa_hwtrig; + uint32_t seqb_hwtrig; + uint32_t comp_flags; + uint32_t overrun_flags; + uint32_t thcmp_flags; + uint32_t error_code; /* error code */ + ADC_SEQ_CALLBK_T seqa_callback; /* For interrupt, it's the end of the sequence A */ + ADC_SEQ_CALLBK_T seqb_callback; /* For interrupt, it's the end of the sequence B */ + ADC_CALLBK_T overrun_callback; /* For interrupt, it's the overrun */ + ADC_CALLBK_T thcmp_callback; /* For interrupt, it's over the threshold */ + uint32_t error_en; /* enable bits for error detection */ + uint32_t thcmp_en; /* enable bits for thcmp detection */ +} ADC_DRIVER_T; /* HEADER_TypeDef *********************************/ + +typedef struct { + uint32_t system_clock; /* System clock */ + uint32_t adc_clock; /* ADC clock */ + uint32_t async_mode; + uint32_t tenbit_mode; + uint32_t lpwr_mode; + uint32_t input_sel; + uint32_t seqa_ctrl; + uint32_t seqb_ctrl; + uint32_t thrsel; + uint32_t thr0_low; + uint32_t thr0_high; + uint32_t thr1_low; + uint32_t thr1_high; + uint32_t error_en; + uint32_t thcmp_en; + uint32_t channel_num; +} ADC_CONFIG_T; + +typedef struct { + uint32_t dma_adc_num; /* DMA channel used for ADC data peripheral to memory transfer */ + uint32_t dma_pinmux_num; /* H/W trigger number. */ + uint32_t dma_handle; /* DMA handle passed to ADC */ + ADC_CALLBK_T dma_done_callback_pt; /* DMA completion callback function */ +} ADC_DMA_CFG_T; + +typedef ErrorCode_t (*ADC_DMA_SETUP_T)(ADC_HANDLE_T handle, ADC_DMA_CFG_T *dma_cfg); + +typedef struct { /* params passed to adc driver function */ + uint32_t *buffer; /* Considering supporting DMA and non-DMA mode, 32-bit buffer is needed for DMA */ + uint32_t driver_mode; /* 0x00: Polling mode, function is blocked until transfer is finished. */ + /* 0x01: Interrupt mode, function exit immediately, callback function is invoked when transfer is finished. */ + /* 0x02: DMA mode, in case DMA block is available, data transferred by ADC is processed by DMA, + and max buffer size is the total number ADC channels, DMA req function is called for ADC DMA + channel setup, then SEQx completion also used as DMA callback function when that ADC conversion/DMA transfer + is finished. */ + uint32_t seqa_hwtrig; /* H/W trigger for sequence A */ + uint32_t seqb_hwtrig; /* H/W trigger for sequence B */ + ADC_CONFIG_T *adc_cfg; + uint32_t comp_flags; + uint32_t overrun_flags; + uint32_t thcmp_flags; + ADC_DMA_CFG_T *dma_cfg; + ADC_SEQ_CALLBK_T seqa_callback_pt; /* SEQA callback function/the same callback on DMA completion if DMA is used for ADCx. */ + ADC_SEQ_CALLBK_T seqb_callback_pt; /* SEQb callback function/the same callback on DMA completion if DMA is used for ADCx. */ + ADC_CALLBK_T overrun_callback_pt; /* Overrun callback function */ + ADC_CALLBK_T thcmp_callback_pt; /* THCMP callback function */ + ADC_DMA_SETUP_T dma_setup_func_pt; /* ADC DMA channel setup function */ +} ADC_PARAM_T; + +/* Typedef Structure for ROM API's */ +typedef struct ADCD_API { + /* ADC Configuration functions */ + uint32_t (*adc_get_mem_size)(void); + ADC_HANDLE_T (*adc_setup)(uint32_t base_addr, uint8_t *ram); + void (*adc_calibration)(ADC_HANDLE_T handle, ADC_CONFIG_T *set); + void (*adc_init)(ADC_HANDLE_T handle, ADC_CONFIG_T *set); + + /* ADC Conversion Functions */ + uint32_t (*adc_seqa_read)(ADC_HANDLE_T handle, ADC_PARAM_T *param); + uint32_t (*adc_seqb_read)(ADC_HANDLE_T handle, ADC_PARAM_T *param); + + /* ADC Interrupt handlers */ + void (*adc_seqa_isr)(ADC_HANDLE_T handle); + void (*adc_seqb_isr)(ADC_HANDLE_T handle); + void (*adc_ovr_isr)(ADC_HANDLE_T handle); + void (*adc_thcmp_isr)(ADC_HANDLE_T handle); + + uint32_t (*adc_get_firmware_version)(void); +} ADCD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_ADC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_can_15xx.h b/lpc_chip_15xx/inc/rom_can_15xx.h new file mode 100644 index 0000000..1076913 --- /dev/null +++ b/lpc_chip_15xx/inc/rom_can_15xx.h @@ -0,0 +1,159 @@ +/* + * @brief LPC15xx CAN ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_CAN_15XX_H_ +#define __ROM_CAN_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CANROM_15XX CHIP: LPC15xx CAN ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/* error status bits */ +#define CAN_ERROR_NONE 0x00000000UL +#define CAN_ERROR_PASS 0x00000001UL +#define CAN_ERROR_WARN 0x00000002UL +#define CAN_ERROR_BOFF 0x00000004UL +#define CAN_ERROR_STUF 0x00000008UL +#define CAN_ERROR_FORM 0x00000010UL +#define CAN_ERROR_ACK 0x00000020UL +#define CAN_ERROR_BIT1 0x00000040UL +#define CAN_ERROR_BIT0 0x00000080UL +#define CAN_ERROR_CRC 0x00000100UL + +typedef void *CAN_HANDLE_T; /* define TYPE for CAN handle pointer */ + +typedef struct _CAN_MSG_OBJ { + uint32_t mode_id; + uint32_t mask; + uint8_t data[8]; + uint8_t dlc; + uint8_t msgobj; +} CAN_MSG_OBJ; + +typedef struct _CAN_CALLBACKS { + void (*CAN_rx)(uint8_t msg_obj); + void (*CAN_tx)(uint8_t msg_obj); + void (*CAN_error)(uint32_t error_info); +} CAN_CALLBACKS; + +typedef struct _CAN_CFG { + uint32_t clkdiv; + uint32_t btr; + uint32_t isr_ena; +} CAN_CFG; + +typedef struct _CAN_ODCONSTENTRY { + uint16_t index; + uint8_t subindex; + uint8_t len; + uint32_t val; +} CAN_ODCONSTENTRY; + +typedef struct _CAN_ODENTRY { + uint16_t index; + uint8_t subindex; + uint8_t entrytype_len; + uint8_t *val; +} CAN_ODENTRY; + +typedef struct _CAN_CANOPENCFG { + uint8_t node_id; + uint8_t msgobj_rx; + uint8_t msgobj_tx; + uint8_t isr_handled; + uint32_t od_const_num; + CAN_ODCONSTENTRY *od_const_table; + uint32_t od_num; + CAN_ODENTRY *od_table; +} CAN_CANOPENCFG; + +typedef struct _CANOPEN_CALLBACKS { + uint32_t (*CANOPEN_sdo_read)(uint16_t index, uint8_t subindex); + uint32_t (*CANOPEN_sdo_write)(uint16_t index, uint8_t subindex, uint8_t *dat_ptr); + uint32_t (*CANOPEN_sdo_seg_read)(uint16_t index, uint8_t subindex, uint8_t + openclose, uint8_t *length, uint8_t *data, uint8_t *last); + uint32_t (*CANOPEN_sdo_seg_write)(uint16_t index, uint8_t subindex, uint8_t + openclose, uint8_t length, uint8_t *data, uint8_t *fast_resp); + uint8_t (*CANOPEN_sdo_req)(uint8_t length_req, uint8_t *req_ptr, uint8_t + *length_resp, uint8_t *resp_ptr); +} CANOPEN_CALLBACKS; + +typedef struct _CAN_API_INIT_PARAM_T { + uint32_t mem_base; /* Address of user-space memory area to use */ + uint32_t can_reg_base; /* Address of start of CAN controller register area */ + CAN_CFG *can_cfg; + CAN_CALLBACKS *callbacks; + CAN_CANOPENCFG *canopen_cfg; + CANOPEN_CALLBACKS *co_callbacks; +} CAN_API_INIT_PARAM_T; + +/** + * @brief LPC15XX CAN ROM API structure + * The CAN profile API provides functions to configure and manage the CAN sub-system. + */ +typedef struct _CAND_API_T { + uint32_t (*hwCAN_GetMemSize)(CAN_API_INIT_PARAM_T *param); + ErrorCode_t (*hwCAN_Init)(CAN_HANDLE_T *phCan, CAN_API_INIT_PARAM_T *param); + void (*hwCAN_Isr)(CAN_HANDLE_T hCan); + void (*hwCAN_ConfigRxmsgobj)(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + uint8_t (*hwCAN_MsgReceive)(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + void (*hwCAN_MsgTransmit)(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + void (*hwCAN_CANopenHandler)(CAN_HANDLE_T hCan); +} CAND_API_T; + +uint32_t hwCAN_GetMemSize(CAN_API_INIT_PARAM_T *param); + +ErrorCode_t hwCAN_Init(CAN_HANDLE_T *phCan, CAN_API_INIT_PARAM_T *param); + +void hwCAN_Isr(CAN_HANDLE_T hCan); + +void hwCAN_ConfigRxmsgobj(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + +uint8_t hwCAN_MsgReceive(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + +void hwCAN_MsgTransmit(CAN_HANDLE_T hCan, CAN_MSG_OBJ *msg_obj); + +void hwCAN_CANopenHandler(CAN_HANDLE_T hCan); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_CAN_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_dma_15xx.h b/lpc_chip_15xx/inc/rom_dma_15xx.h new file mode 100644 index 0000000..e51250a --- /dev/null +++ b/lpc_chip_15xx/inc/rom_dma_15xx.h @@ -0,0 +1,206 @@ +/* + * @brief LPC15xx DMA ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_DMA_15XX_H_ +#define __ROM_DMA_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup DMAROM_15XX CHIP: LPC15xx DMA ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/* Bit definitions for DMA ROM Channel Configuration Structure */ +#define DMA_ROM_CH_EVENT_SWTRIG ((uint8_t) 0) +#define DMA_ROM_CH_EVENT_PERIPH ((uint8_t) 1) +#define DMA_ROM_CH_EVENT_HWTRIG ((uint8_t) 2) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_1 ((uint8_t) 0 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_2 ((uint8_t) 1 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_4 ((uint8_t) 2 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_8 ((uint8_t) 3 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_16 ((uint8_t) 4 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_32 ((uint8_t) 5 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_64 ((uint8_t) 6 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_128 ((uint8_t) 7 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_256 ((uint8_t) 8 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_512 ((uint8_t) 9 << 0) +#define DMA_ROM_CH_HWTRIG_BURSTPOWER_1024 ((uint8_t) 10 << 0) +#define DMA_ROM_CH_HWTRIG_SRC_WRAP_EN ((uint8_t) 1 << 4) +#define DMA_ROM_CH_HWTRIG_DEST_WRAP_EN ((uint8_t) 1 << 5) +#define DMA_ROM_CH_HWTRIG_BURST_EN ((uint8_t) 1 << 6) +/* Bit definitions for DMA ROM Task Configuration Structure */ +#define DMA_ROM_TASK_CFG_PING_PONG_EN ((uint8_t) 1 << 0) +#define DMA_ROM_TASK_CFG_SW_TRIGGER ((uint8_t) 1 << 1) +#define DMA_ROM_TASK_CFG_CLR_TRIGGER ((uint8_t) 1 << 2) +#define DMA_ROM_TASK_CFG_SEL_INTA ((uint8_t) 1 << 3) +#define DMA_ROM_TASK_CFG_SEL_INTB ((uint8_t) 1 << 4) +#define DMA_ROM_TASK_DATA_WIDTH_8 ((uint8_t) 0 ) +#define DMA_ROM_TASK_DATA_WIDTH_16 ((uint8_t) 1 ) +#define DMA_ROM_TASK_DATA_WIDTH_32 ((uint8_t) 2 ) +#define DMA_ROM_TASK_SRC_INC_0 ((uint8_t) 0 << 2) +#define DMA_ROM_TASK_SRC_INC_1 ((uint8_t) 1 << 2) +#define DMA_ROM_TASK_SRC_INC_2 ((uint8_t) 2 << 2) +#define DMA_ROM_TASK_SRC_INC_4 ((uint8_t) 3 << 2) +#define DMA_ROM_TASK_DEST_INC_0 ((uint8_t) 0 << 4) +#define DMA_ROM_TASK_DEST_INC_1 ((uint8_t) 1 << 4) +#define DMA_ROM_TASK_DEST_INC_2 ((uint8_t) 2 << 4) +#define DMA_ROM_TASK_DEST_INC_4 ((uint8_t) 3 << 4) +/** + * @brief DMA handle type + */ +typedef void *DMA_HANDLE_T; + +/** + * @brief DMA channel callback function type + * @param res0: error code + * @param res1: 0 = INTA is issued, 1 = INTB is issued + */ +typedef void (*CALLBK_T)(uint32_t res0, uint32_t res1); + +/** + * @brief DMA ROM drivers channel control structure + */ +typedef struct { + uint8_t event; /*!< event type selection for DMA transfer + - 0: software request + - 1: peripheral request + - 2: hardware trigger + - others: reserved */ + uint8_t hd_trigger; /*!< In case hardware trigger is enabled, the trigger burst is setup here. + NOTE: Rising edge triggered is fixed + - bit0~bit3: burst size + - 0: burst size =1, 1: 2^1, 2: 2^2,... 10: 1024, others: reserved. + - bit4: Source Burst Wrap + - 0: Source burst wrapping is not enabled + - 1: Source burst wrapping is enabled + - bit5: Destination Burst Wrap + - 0: Destination burst wrapping is not enabled + - 1: Destination burst wrapping is enabled + - bit6: Trigger Burst + - 0: Hardware trigger cause a single transfer + - 1: Hardware trigger cause a burst transfer + - bit7: reserved */ + uint8_t priority; /*!< priority level + - 0 -> 7: Highest priority -> Lowest priority. + - other: reserved. */ + uint8_t reserved0; + CALLBK_T cb_func; /*!< callback function, Callback function is + only invoked when INTA or INTB is enabled. */ +} DMA_CHANNEL_T; + +/** + * @brief DMA ROM driver's TASK parameter structure + */ +typedef struct { + uint8_t ch_num; /*!< DMA channel number */ + uint8_t config; /*!< configuration of this task + - bit0: Ping_Pong transfer + - 0: Not Ping_Pong transfer + - 1: Linked with previous task for Ping_Pong transfer + - bit1: Software Trigger. + - 0: the trigger for this channel is not set. + - 1: the trigger for this channel is set immediately. + - bit2: Clear Trigger + - 0: The trigger is not cleared when this task is finished. + - 1: The trigger is cleared when this task is finished. + - bit3: Select INTA + - 0: No IntA. + - 1: The IntB flag for this channel will be set when this task is finished. + bit4: Select INTB + 0: No IntB. + 1: The IntB flag for this channel will be set when this task is finished. + bit5~bit7: reserved + */ + + uint8_t data_type; /*!< + - bit0~bit1: Data width. 0: 8-bit, 1: 16-bit, 2: 32-bit, 3: reserved + - bit2~bit3: How is source address incremented? + - 0: The source address is not incremented for each transfer. + 1: The source address is incremented by the amount specified by Width for each transfer. + 2: The source address is incremented by 2 times the amount specified by Width for each transfer. + 3: The source address is incremented by 4 times the amount specified by Width for each transfer. + - bit4~bit5: How is the destination address incremented? + 0: The destination address is not incremented for each transfer. + 1: The destination address is incremented by the amount specified by Width for each transfer. + 2: The destination address is incremented by 2 times the amount specified by Width for each transfer. + 3: The destination address is incremented by 4 times the amount specified by Width for each transfer. + - bit6~bit7: reserved. */ + uint8_t reserved0; + uint16_t data_length; /*!< 0: 1 transfer, 1: 2 transfer, ..., 1023: 1024 transfer. Others: reserved.*/ + uint16_t reserved1; + uint32_t src; /*!< Source data end address */ + uint32_t dst; /*!< Destination end address */ + uint32_t task_addr; /*!< the address of RAM for saving this task. + (NOTE: each task need 16 bytes RAM for storing configuration, + and DMA API could set it according user input parameter, + but it is responsible of user to allocate this RAM space and + make sure that the base address must be 16-byte alignment. + And if user has setup the next_task(!=0), the dma_task_link + must be called for this task setup, otherwise unpredictable error will happen.) */ +} DMA_TASK_T; + +/** + * @brief DMA ROM API structure + * The DMA API handles DMA set-up and transfers. + */ +typedef struct DMAD_API { + /** DMA ISR routine */ + void (*dma_isr)(DMA_HANDLE_T *handle); + /** Get memory size needed for DMA. */ + uint32_t (*dma_get_mem_size)(void); + /** Set up DMA. */ + DMA_HANDLE_T * (*dma_setup)(uint32_t base_addr, uint8_t * ram); + /** Enable DMA channel and set-up basic DMA transfer. */ + ErrorCode_t (*dma_init)(DMA_HANDLE_T *handle, DMA_CHANNEL_T *channel, DMA_TASK_T *task); + /** Create linked transfer. */ + ErrorCode_t (*dma_link)(DMA_HANDLE_T *handle, DMA_TASK_T *task, uint8_t valid); + /** Set a task to valid. */ + ErrorCode_t (*dma_set_valid)(DMA_HANDLE_T *handle, uint8_t chl_num); + /** Pause DMA transfer on a given channel. */ + ErrorCode_t (*dma_pause)(DMA_HANDLE_T *handle, uint8_t chl_num); + /** Resume DMA transfer. */ + ErrorCode_t (*dma_unpause)(DMA_HANDLE_T *handle, uint8_t chl_num); + /** Cancel DMA transfer on a given channel.*/ + ErrorCode_t (*dma_abort)(DMA_HANDLE_T *handle, uint8_t chl_num); +} DMAD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_DMA_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_i2c_15xx.h b/lpc_chip_15xx/inc/rom_i2c_15xx.h new file mode 100644 index 0000000..c9448eb --- /dev/null +++ b/lpc_chip_15xx/inc/rom_i2c_15xx.h @@ -0,0 +1,124 @@ +/* + * @brief LPC15XX I2C ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_I2C_15XX_H_ +#define __ROM_I2C_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CHIP_I2CROM_15XX CHIP: LPC15xx I2C ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/** + * @brief LPC15XX I2C ROM driver handle structure + */ +typedef void *I2C_HANDLE_T; + +/** + * @brief LPC15XX I2C ROM driver callback function + */ +typedef void (*I2C_CALLBK_T)(uint32_t err_code, uint32_t n); + +/** + * LPC15XX I2C ROM driver parameter structure + */ +typedef struct I2C_PARAM { + uint32_t num_bytes_send; /*!< No. of bytes to send */ + uint32_t num_bytes_rec; /*!< No. of bytes to receive */ + uint8_t *buffer_ptr_send; /*!< Pointer to send buffer */ + uint8_t *buffer_ptr_rec; /*!< Pointer to receive buffer */ + I2C_CALLBK_T func_pt; /*!< Callback function */ + uint8_t stop_flag; /*!< Stop flag */ + uint8_t dummy[3]; +} I2C_PARAM_T; + +/** + * LPC15XX I2C ROM driver result structure + */ +typedef struct I2C_RESULT { + uint32_t n_bytes_sent; /*!< No. of bytes sent */ + uint32_t n_bytes_recd; /*!< No. of bytes received */ +} I2C_RESULT_T; + +/** + * LPC15XX I2C ROM driver modes enum + */ +typedef enum CHIP_I2C_MODE { + IDLE, /*!< IDLE state */ + MASTER_SEND, /*!< Master send state */ + MASTER_RECEIVE, /*!< Master Receive state */ + SLAVE_SEND, /*!< Slave send state */ + SLAVE_RECEIVE /*!< Slave receive state */ +} CHIP_I2C_MODE_T; + +/** + * LPC15XX I2C ROM driver APIs structure + */ +typedef struct I2CD_API { + /*!< Interrupt Support Routine */ + void (*i2c_isr_handler)(I2C_HANDLE_T *handle); + /*!< MASTER functions */ + ErrorCode_t (*i2c_master_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_tx_rx_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_tx_rx_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + + /*!< SLAVE functions */ + ErrorCode_t (*i2c_slave_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_set_slave_addr)(I2C_HANDLE_T *handle, uint32_t slave_addr_0_3, uint32_t slave_mask_0_3); + + /*!< OTHER support functions */ + uint32_t (*i2c_get_mem_size)(void); + I2C_HANDLE_T *(*i2c_setup)(uint32_t i2c_base_addr, uint32_t * start_of_ram); + ErrorCode_t (*i2c_set_bitrate)(I2C_HANDLE_T *handle, uint32_t p_clk_in_hz, uint32_t bitrate_in_bps); + uint32_t (*i2c_get_firmware_version)(void); + CHIP_I2C_MODE_T (*i2c_get_status)(I2C_HANDLE_T *handle); + ErrorCode_t (*i2c_set_timeout)(I2C_HANDLE_T *handle, uint32_t timeout); +} I2CD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_I2C_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_pwr_15xx.h b/lpc_chip_15xx/inc/rom_pwr_15xx.h new file mode 100644 index 0000000..48874e2 --- /dev/null +++ b/lpc_chip_15xx/inc/rom_pwr_15xx.h @@ -0,0 +1,117 @@ +/* + * @brief LPC15xx Power ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_PWR_15XX_H_ +#define __ROM_PWR_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PWRROM_15XX CHIP: LPC15xx Power ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/** + * @brief LPC15XX Power ROM APIs - set_pll mode options + */ +#define CPU_FREQ_EQU 0 +#define CPU_FREQ_LTE 1 +#define CPU_FREQ_GTE 2 +#define CPU_FREQ_APPROX 3 + +/** + * @brief LPC15XX Power ROM APIs - set_pll response0 options + */ +#define PLL_CMD_SUCCESS 0 +#define PLL_INVALID_FREQ 1 +#define PLL_INVALID_MODE 2 +#define PLL_FREQ_NOT_FOUND 3 +#define PLL_NOT_LOCKED 4 + +/** + * @brief LPC15XX Power ROM APIs - set_power mode options + */ +#define PWR_DEFAULT 0 +#define PWR_CPU_PERFORMANCE 1 +#define PWR_EFFICIENCY 2 +#define PWR_LOW_CURRENT 3 + +/** + * @brief LPC15XX Power ROM APIs - set_power response0 options + */ +#define PWR_CMD_SUCCESS 0 +#define PWR_INVALID_FREQ 1 +#define PWR_INVALID_MODE 2 + +/** + * @brief LPC15XX Power ROM APIs - power_mode_configure mode options + */ +#define PMU_SLEEP 0 +#define PMU_DEEP_SLEEP 1 +#define PMU_POWERDOWN 2 +#define PMU_DEEP_POWERDOWN 3 + +/** + * @brief LPC15XX Power ROM APIs - power_mode_configure peripheral control bits + */ +#define PMU_PD_WDOSC (1 << 0) +#define PMU_PD_BOD (1 << 1) +#define PMU_PD_ACMP0 (1 << 2) +#define PMU_PD_ACMP1 (1 << 3) +#define PMU_PD_ACMP2 (1 << 4) +#define PMU_PD_ACMP3 (1 << 5) +#define PMU_PD_IREF (1 << 6) +#define PMU_PD_TS (1 << 7) + +/** + * @brief LPC15xx Power ROM API structure + * The power profile API provides functions to configure the system clock and optimize the + * system setting for lowest power consumption. + */ +typedef struct PWRD_API { + void (*set_pll)(uint32_t cmd[], uint32_t resp[]); /*!< Set PLL function */ + void (*set_power)(uint32_t cmd[], uint32_t resp[]); /*!< Set power function */ + void (*power_mode_configure)(uint32_t power_mode, uint32_t peripheral_ctrl);/*!< Sets the chip is low power modes */ + void (*set_aclkgate)(uint32_t aclkgate); + uint32_t (*get_aclkgate)(void); +} PWRD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_PWR_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_spi_15xx.h b/lpc_chip_15xx/inc/rom_spi_15xx.h new file mode 100644 index 0000000..08b9042 --- /dev/null +++ b/lpc_chip_15xx/inc/rom_spi_15xx.h @@ -0,0 +1,141 @@ +/* + * @brief LPC15xx SPI ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_SPI_15XX_H_ +#define __ROM_SPI_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SPIROM_15XX CHIP: LPC15xx SPI ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/** + * @brief SPI handle type + * The handle to the instance of the SPI driver. Each SPI has one handle, so there can be + * several handles for each SPI block. This handle is created by Init API and used by the + * transfer functions for the corresponding SPI block. + */ +typedef void *SPI_HANDLE_T; + +/** + * @brief SPI DMA configuration structure + */ +typedef struct { + uint32_t dma_txd_num; /*!< DMA channel number in case DMA mode is enabled. */ + uint32_t dma_rxd_num; /*!< In order to do a SPI RX DMA, a SPI TX DMA is also needed to generated clock. */ + DMA_HANDLE_T hDMA; /*!< DMA handle */ +} SPI_DMA_CFG_T; + +/** + * @brief SPI interrupt callback function type + * @param err_code: SPI error code + * @param n: In interrupt mode, this parameter indicates the number of SPI frames. + * In DMA mode, this parameter is always zero. + */ +typedef void (*SPI_CALLBK_T)(ErrorCode_t err_code, uint32_t n); + +/** + * @brief SPI DMA setup callback function type. + * To set up the DMA channel, the source address, destination address, DMA transfer + * length, DMA request information must be retrieved from the driver structure which has + * been originally passed from the ROM_SPI_PARAM_T structure. + * @param handle: SPI driver handle + * @param dma_cfg: DMA configuration. + */ +typedef ErrorCode_t (*SPI_DMA_REQ_T)(SPI_HANDLE_T handle, SPI_DMA_CFG_T *dma_cfg); + +/** + * @brief SPI configuration structure + */ +typedef struct { + uint32_t delay; /*!< Configures the delay between SSEL and data transfers and between frames. The + value is the content of the SPI DLY register. */ + uint32_t divider; /*!< Clock divider value DIVVAL in the SPI DIV register. */ + uint32_t config; /*!< Enable SPI, configure master/slave, configure signal phase and polarity. The + value is the content of the SPI CFG register. */ + uint32_t error_en; /*!< Enables the receive overrun and transmit underrun error interrupts. */ +} SPI_CONFIG_T; + +/** + * @brief SPI configuration parameter structure + */ +typedef struct { + uint16_t *tx_buffer; /*!< Tx buffer */ + uint16_t *rx_buffer; /*!< Rx buffer */ + uint32_t size; /*!< size of the SPI transfer. A transfer can consist of several transmits of the + TXCTLDAT register and of several frames. */ + uint32_t fsize_sel; /*!< write the contents of the SPI TXCTL register to select the data length and the + slave select lines. In slave mode, you need to only select the data length. */ + uint32_t eof_flag; /*!< EOF flag. EOF( end of frame ) is needed if set. EOF delay will not be asserted without this flag. */ + uint32_t tx_rx_flag; /*!< Tx & Rx mode flag. 0 is TX only, 1 is RX only, 0x2 is TX and RX */ + uint32_t driver_mode; /*!< Driver mode. + - 0x00: Polling mode. Function is blocked until transfer is finished. + - 0x01: Interrupt mode. Function exits immediately and a call back function is invoked when the transfer has finished + - 0x02: DMA mode. Data transferred by SPI is processed by DMA. + The DMA_req function is called foe SPI DMA channel set up. + The callback function indicates when the transfer is complete. */ + SPI_DMA_CFG_T *dma_cfg; /*!< DMA configuration */ + SPI_CALLBK_T cb; /*!< SPI interrupt callback function */ + SPI_DMA_REQ_T dma_cb; /*!< SPI DMA channel set-up call back function. */ +} SPI_PARAM_T; + +/** + * @brief SPI ROM API structure + * The SPI API handles SPI data transfer in master and slave modes. + */ +typedef struct { + /** Memory size for one SPI instance */ + uint32_t (*spi_get_mem_size)(void); + /** Set up SPI instance and return handle*/ + SPI_HANDLE_T (*spi_setup)(uint32_t base_addr, uint8_t *ram); + /** Set up SPI operating mode */ + void (*spi_init)(SPI_HANDLE_T handle, SPI_CONFIG_T *set); + /** Send or receive data in master mode*/ + uint32_t (*spi_master_transfer)(SPI_HANDLE_T handle, SPI_PARAM_T *param); + /** Send or receive data in slave mode*/ + uint32_t (*spi_slave_transfer)(SPI_HANDLE_T handle, SPI_PARAM_T *param); + /** Interrupt service routine */ + void (*spi_isr)(SPI_HANDLE_T handle); +} SPID_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_SPI_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/rom_uart_15xx.h b/lpc_chip_15xx/inc/rom_uart_15xx.h new file mode 100644 index 0000000..4e4777b --- /dev/null +++ b/lpc_chip_15xx/inc/rom_uart_15xx.h @@ -0,0 +1,181 @@ +/* + * @brief LPC15XX UART ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_UART_15XX_H_ +#define __ROM_UART_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup UARTROM_15XX CHIP: LPC15xx UART ROM API declarations and functions + * @ingroup ROMAPI_15XX + * @{ + */ + +/** + * @brief UART ROM driver - UART errors in UART configuration used in uart_init function + */ +#define OVERRUN_ERR_EN (1 << 0) /*!< Bit 0: Enable overrun error */ +#define UNDERRUN_ERR_EN (1 << 1) /*!< Bit 1: Enable underrun error */ +#define FRAME_ERR_EN (1 << 2) /*!< Bit 2: enable frame error */ +#define PARITY_ERR_EN (1 << 3) /*!< Bit 3: enable parity error */ +#define RXNOISE_ERR_EN (1 << 4) /*!< Bit 4: enable receive noise error */ + +/** + * Macros for UART errors + */ +/*!< Enable all the UART errors */ +#define ALL_ERR_EN (OVERRUN_ERR_EN | UNDERRUN_ERR_EN | FRAME_ERR_EN | PARITY_ERR_EN | \ + RXNOISE_ERR_EN) +/*!< Disable all the errors */ +#define NO_ERR_EN (0) + +/** + * Transfer mode values in UART parameter structure. + * Used in uart_get_line & uart_put_line function + */ +/*!< 0x00: uart_get_line: stop transfer when the buffer is full */ +/*!< 0x00: uart_put_line: stop transfer when the buffer is empty */ +#define TX_MODE_BUF_EMPTY (0x00) +#define RX_MODE_BUF_FULL (0x00) +/*!< 0x01: uart_get_line: stop transfer when CRLF are received */ +/*!< 0x01: uart_put_line: transfer stopped after reaching \0 and CRLF is sent out after that */ +#define TX_MODE_SZERO_SEND_CRLF (0x01) +#define RX_MODE_CRLF_RECVD (0x01) +/*!< 0x02: uart_get_line: stop transfer when LF are received */ +/*!< 0x02: uart_put_line: transfer stopped after reaching \0. And LF is sent out after that */ +#define TX_MODE_SZERO_SEND_LF (0x02) +#define RX_MODE_LF_RECVD (0x02) +/*!< 0x03: uart_get_line: RESERVED */ +/*!< 0x03: uart_put_line: transfer stopped after reaching \0 */ +#define TX_MODE_SZERO (0x03) + +/** + * @brief UART ROM driver modes + */ +#define DRIVER_MODE_POLLING (0x00) /*!< Polling mode */ +#define DRIVER_MODE_INTERRUPT (0x01) /*!< Interrupt mode */ +#define DRIVER_MODE_DMA (0x02) /*!< DMA mode */ + +/** + * @brief UART ROM driver UART handle + */ +typedef void *UART_HANDLE_T; + +/** + * @brief UART ROM driver UART callback function + */ +typedef void (*UART_CALLBK_T)(uint32_t err_code, uint32_t n); + +/** + * @brief UART ROM driver UART DMA callback function + */ +typedef void (*UART_DMA_REQ_T)(uint32_t src_adr, uint32_t dst_adr, uint32_t size); + +/** + * @brief UART ROM driver configutaion structure + */ +typedef struct { + uint32_t sys_clk_in_hz; /*!< System clock in Hz */ + uint32_t baudrate_in_hz; /*!< Baud rate in Hz */ + uint8_t config; /*!< Configuration value */ + /*!< bit1:0 Data Length: 00: 7 bits length, 01: 8 bits length, others: reserved */ + /*!< bit3:2 Parity: 00: No Parity, 01: reserved, 10: Even, 11: Odd */ + /*!< bit4: Stop Bit(s): 0: 1 Stop bit, 1: 2 Stop bits */ + uint8_t sync_mod; /*!< Sync mode settings */ + /*!< bit0: Mode: 0: Asynchronous mode, 1: Synchronous mode */ + /*!< bit1: 0: Un_RXD is sampled on the falling edge of SCLK */ + /*!< 1: Un_RXD is sampled on the rising edge of SCLK */ + /*!< bit2: 0: Start and stop bits are transmitted as in asynchronous mode) */ + /*!< 1: Start and stop bits are not transmitted) */ + /*!< bit3: 0: The UART is a slave in Synchronous mode */ + /*!< 1: The UART is a master in Synchronous mode */ + uint16_t error_en; /*!< Errors to be enabled */ + /*!< bit0: Overrun Errors Enabled */ + /*!< bit1: Underrun Errors Enabled */ + /*!< bit2: FrameErr Errors Enabled */ + /*!< bit3: ParityErr Errors Enabled */ + /*!< bit4: RxNoise Errors Enabled */ +} UART_CONFIG_T; + +/** + * @brief UART ROM driver parameter structure + */ +typedef struct { + uint8_t *buffer; /*!< Pointer to data buffer */ + uint32_t size; /*!< Size of the buffer */ + uint16_t transfer_mode; /*!< Transfer mode settings */ + /*!< 0x00: uart_get_line: stop transfer when the buffer is full */ + /*!< 0x00: uart_put_line: stop transfer when the buffer is empty */ + /*!< 0x01: uart_get_line: stop transfer when CRLF are received */ + /*!< 0x01: uart_put_line: transfer stopped after reaching \0 and CRLF is sent out after that */ + /*!< 0x02: uart_get_line: stop transfer when LF are received */ + /*!< 0x02: uart_put_line: transfer stopped after reaching \0 and LF is sent out after that */ + /*!< 0x03: uart_get_line: RESERVED */ + /*!< 0x03: uart_put_line: transfer stopped after reaching \0 */ + uint8_t driver_mode; /*!< Driver mode */ + /*!< 0x00: Polling mode, function blocked until transfer completes */ + /*!< 0x01: Interrupt mode, function immediately returns, callback invoked when transfer completes */ + /*!< 0x02: DMA mode, in case DMA block is available, DMA req function is called for UART DMA channel setup, then callback function indicate that transfer completes */ + uint8_t dma_num; /*!< DMA channel number in case DMA mode is enabled */ + UART_CALLBK_T callback_func_pt; + uint32_t dma; /* DMA handler */ +} UART_PARAM_T; + +/** + * @brief UART ROM driver APIs structure + */ +typedef struct UART_API { + /* UART Configuration functions */ + uint32_t (*uart_get_mem_size)(void); /*!< Get the memory size needed by one Min UART instance */ + UART_HANDLE_T (*uart_setup)(uint32_t base_addr, uint8_t *ram); /*!< Setup Min UART instance with provided memory and return the handle to this instance */ + uint32_t (*uart_init)(UART_HANDLE_T handle, UART_CONFIG_T *set); /*!< Setup baud rate and operation mode for uart, then enable uart */ + + /* UART polling functions block until completed */ + uint8_t (*uart_get_char)(UART_HANDLE_T handle); /*!< Receive one Char from uart. This functions is only returned after Char is received. In case Echo is enabled, the received data is sent out immediately */ + void (*uart_put_char)(UART_HANDLE_T handle, uint8_t data); /*!< Send one Char through uart. This function is only returned after data is sent */ + uint32_t (*uart_get_line)(UART_HANDLE_T handle, UART_PARAM_T *param); /*!< Receive multiple bytes from UART */ + uint32_t (*uart_put_line)(UART_HANDLE_T handle, UART_PARAM_T *param); /*!< Send string (end with \0) or raw data through UART */ + + /* UART interrupt functions return immediately and callback when completed */ + void (*uart_isr)(UART_HANDLE_T handle); /*!< UART interrupt service routine. To use this routine, the corresponding USART interrupt must be enabled. This function is invoked by the user ISR */ +} UARTD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_UART_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/romapi_15xx.h b/lpc_chip_15xx/inc/romapi_15xx.h new file mode 100644 index 0000000..874ca7b --- /dev/null +++ b/lpc_chip_15xx/inc/romapi_15xx.h @@ -0,0 +1,115 @@ +/* + * @brief LPC15xx ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROMAPI_15XX_H_ +#define __ROMAPI_15XX_H_ + +#include "iap.h" +#include "eeprom.h" +#include "error.h" +#include "rom_i2c_15xx.h" +#include "rom_pwr_15xx.h" +#include "rom_uart_15xx.h" +#include "rom_can_15xx.h" +#include "rom_dma_15xx.h" +#include "rom_spi_15xx.h" +#include "rom_adc_15xx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup ROMAPI_15XX CHIP: LPC15xx ROM API declarations and functions + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15XX High level ROM API structure + */ +typedef struct { + const uint32_t pUSBD; /*!< USBD API function table base address */ + const uint32_t reserved0; /*!< Reserved */ + const CAND_API_T *pCAND; /*!< C_CAN API function table base address */ + const PWRD_API_T *pPWRD; /*!< Power API function table base address */ + const uint32_t reserved1; /*!< Reserved */ + const I2CD_API_T *pI2CD; /*!< I2C driver API function table base address */ + const DMAD_API_T *pDMAD; /*!< DMA driver API function table base address */ + const SPID_API_T *pSPID; /*!< I2C driver API function table base address */ + const ADCD_API_T *pADCD; /*!< ADC driver API function table base address */ + const UARTD_API_T *pUARTD; /*!< UART driver API function table base address */ +} LPC_ROM_API_T; + +/* Pointer to ROM API function address */ +#define LPC_ROM_API_BASE_LOC 0x03000200UL +#define LPC_ROM_API (*(LPC_ROM_API_T * *) LPC_ROM_API_BASE_LOC) + +/* Pointer to @ref CAND_API_T functions in ROM */ +#define LPC_CAND_API ((LPC_ROM_API)->pCAND) + +/* Pointer to @ref PWRD_API_T functions in ROM */ +#define LPC_PWRD_API ((LPC_ROM_API)->pPWRD) + +/* Pointer to @ref I2CD_API_T functions in ROM */ +#define LPC_I2CD_API ((LPC_ROM_API)->pI2CD) + +/* Pointer to @ref DMAD_API_T functions in ROM for DMA */ +#define LPC_DMAD_API ((LPC_ROM_API)->pDMAD) + +/* Pointer to @ref SPID_API_T functions in ROM for DMA */ +#define LPC_SPID_API ((LPC_ROM_API)->pSPID) + +/* Pointer to @ref ADCD_API_T functions in ROM for pADCD */ +#define LPC_ADCD_API ((LPC_ROM_API)->pADCD) + +/* Pointer to @ref UARTD_API_T functions in ROM for UARTs */ +#define LPC_UARTD_API ((LPC_ROM_API)->pUARTD) + +/* Pointer to ROM IAP entry functions */ +#define IAP_ENTRY_LOCATION 0x03000205UL + +/** + * @brief LPC15XX IAP_ENTRY API function type + */ +static INLINE void iap_entry(unsigned int cmd_param[5], unsigned int status_result[4]) +{ + ((IAP_ENTRY_T) IAP_ENTRY_LOCATION)(cmd_param, status_result); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROMAPI_11U6X_H_ */ diff --git a/lpc_chip_15xx/inc/rtc_15xx.h b/lpc_chip_15xx/inc/rtc_15xx.h new file mode 100644 index 0000000..5e60a1a --- /dev/null +++ b/lpc_chip_15xx/inc/rtc_15xx.h @@ -0,0 +1,308 @@ +/* + * @brief LPC15xx RTC chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __RTC_15XX_H_ +#define __RTC_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup RTC_15XX CHIP: LPC15xx RTC driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15xx Pin Interrupt and Pattern Match register block structure + */ +typedef struct { /*!< RTC */ + __IO uint32_t CTRL; /*!< RTC control register */ + __IO uint32_t MATCH; /*!< PRTC match (alarm) register */ + __IO uint32_t COUNT; /*!< RTC counter register */ + __IO uint32_t WAKE; /*!< RTC high-resolution/wake-up timer control register */ +} LPC_RTC_T; + +/* CTRL register defniitions */ +#define RTC_CTRL_SWRESET (1 << 0) /*!< Apply reset to RTC */ +#define RTC_CTRL_OFD (1 << 1) /*!< Oscillator fail detect status (failed bit) */ +#define RTC_CTRL_ALARM1HZ (1 << 2) /*!< RTC 1 Hz timer alarm flag status (match) bit */ +#define RTC_CTRL_WAKE1KHZ (1 << 3) /*!< RTC 1 kHz timer wake-up flag status (timeout) bit */ +#define RTC_CTRL_ALARMDPD_EN (1 << 4) /*!< RTC 1 Hz timer alarm for Deep power-down enable bit */ +#define RTC_CTRL_WAKEDPD_EN (1 << 5) /*!< RTC 1 kHz timer wake-up for Deep power-down enable bit */ +#define RTC_CTRL_RTC1KHZ_EN (1 << 6) /*!< RTC 1 kHz clock enable bit */ +#define RTC_CTRL_RTC_EN (1 << 7) /*!< RTC enable bit */ + +/** + * @brief Initialize the RTC peripheral + * @param pRTC : RTC peripheral selected + * @return None + */ +STATIC INLINE void Chip_RTC_Init(LPC_RTC_T *pRTC) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_RTC); +} + +/** + * @brief De-initialize the RTC peripheral + * @param pRTC : RTC peripheral selected + * @return None + */ +STATIC INLINE void Chip_RTC_DeInit(LPC_RTC_T *pRTC) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_RTC); +} + +/** + * @brief Enable RTC options + * @param pRTC : The base address of RTC block + * @param flags : And OR'ed value of RTC_CTRL_* definitions to enable + * @return Nothing + * @note You can enable multiple RTC options at once using this function + * by OR'ing them together. It is recommended to only use the + * RTC_CTRL_ALARMDPD_EN, RTC_CTRL_WAKEDPD_EN, RTC_CTRL_RTC1KHZ_EN, and + * RTC_CTRL_RTC_EN flags with this function. + */ +STATIC INLINE void Chip_RTC_EnableOptions(LPC_RTC_T *pRTC, uint32_t flags) +{ + pRTC->CTRL |= flags; +} + +/** + * @brief Disable RTC options + * @param pRTC : The base address of RTC block + * @param flags : And OR'ed value of RTC_CTRL_* definitions to disable + * @return Nothing + * @note You can enable multiple RTC options at once using this function + * by OR'ing them together. It is recommended to only use the + * RTC_CTRL_ALARMDPD_EN, RTC_CTRL_WAKEDPD_EN, RTC_CTRL_RTC1KHZ_EN, and + * RTC_CTRL_RTC_EN flags with this function. + */ +STATIC INLINE void Chip_RTC_DisableOptions(LPC_RTC_T *pRTC, uint32_t flags) +{ + pRTC->CTRL &= ~flags; +} + +/** + * @brief Reset RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note The RTC state will be returned to it's default. + */ +STATIC INLINE void Chip_RTC_Reset(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_SWRESET); + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_SWRESET); +} + +/** + * @brief Enables the RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_EnableOptions() with the + * RTC_CTRL_RTC_EN flag to enable the RTC. + */ +STATIC INLINE void Chip_RTC_Enable(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_RTC_EN); +} + +/** + * @brief Disables the RTC + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_DisableOptions() with the + * RTC_CTRL_RTC_EN flag to enable the RTC. + */ +STATIC INLINE void Chip_RTC_Disable(LPC_RTC_T *pRTC) +{ + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_RTC_EN); +} + +/** + * @brief Enables the RTC 1KHz high resolution timer + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_EnableOptions() with the + * RTC_CTRL_RTC1KHZ_EN flag to enable the high resolution + * timer. + */ +STATIC INLINE void Chip_RTC_Enable1KHZ(LPC_RTC_T *pRTC) +{ + Chip_RTC_EnableOptions(pRTC, RTC_CTRL_RTC1KHZ_EN); +} + +/** + * @brief Disables the RTC 1KHz high resolution timer + * @param pRTC : The base address of RTC block + * @return Nothing + * @note You can also use Chip_RTC_DisableOptions() with the + * RTC_CTRL_RTC1KHZ_EN flag to disable the high resolution + * timer. + */ +STATIC INLINE void Chip_RTC_Disable1KHZ(LPC_RTC_T *pRTC) +{ + Chip_RTC_DisableOptions(pRTC, RTC_CTRL_RTC1KHZ_EN); +} + +/** + * @brief Enables selected RTC wakeup events + * @param pRTC : The base address of RTC block + * @param ints : Wakeup events to enable + * @return Nothing + * @note Select either one or both (OR'ed) RTC_CTRL_ALARMDPD_EN + * and RTC_CTRL_WAKEDPD_EN values to enabled. You can also + * use Chip_RTC_EnableOptions() with the flags to enable + * the events. + */ +STATIC INLINE void Chip_RTC_EnableWakeup(LPC_RTC_T *pRTC, uint32_t ints) +{ + Chip_RTC_EnableOptions(pRTC, ints); +} + +/** + * @brief Disables selected RTC wakeup events + * @param pRTC : The base address of RTC block + * @param ints : Wakeup events to disable + * @return Nothing + * @note Select either one or both (OR'ed) RTC_CTRL_ALARMDPD_EN + * and RTC_CTRL_WAKEDPD_EN values to disabled. You can also + * use Chip_RTC_DisableOptions() with the flags to disable + * the events. + */ +STATIC INLINE void Chip_RTC_DisableWakeup(LPC_RTC_T *pRTC, uint32_t ints) +{ + Chip_RTC_DisableOptions(pRTC, ints); +} + +/** + * @brief Clears latched RTC statuses + * @param pRTC : The base address of RTC block + * @param stsMask : OR'ed status bits to clear + * @return Nothing + * @note Use and OR'ed stsMask value of RTC_CTRL_OFD, RTC_CTRL_ALARM1HZ, + * and RTC_CTRL_WAKE1KHZ to clear specific RTC states. + */ +STATIC INLINE uint32_t Chip_RTC_ClearStatus(LPC_RTC_T *pRTC, uint32_t stsMask) +{ + return pRTC->CTRL; +} + +/** + * @brief Return RTC control/status register + * @param pRTC : The base address of RTC block + * @return The current RTC control/status register + * @note Mask the return value with a RTC_CTRL_* definitions to determine + * which bits are set. For example, mask the return value with + * RTC_CTRL_ALARM1HZ to determine if the alarm interrupt is pending. + */ +STATIC INLINE uint32_t Chip_RTC_GetStatus(LPC_RTC_T *pRTC) +{ + return pRTC->CTRL; +} + +/** + * @brief Set RTC match value for alarm status/interrupt + * @param pRTC : The base address of RTC block + * @param count : Alarm event time + * @return Nothing + */ +STATIC INLINE void Chip_RTC_SetAlarm(LPC_RTC_T *pRTC, uint32_t count) +{ + pRTC->MATCH = count; +} + +/** + * @brief Return the RTC match value used for alarm status/interrupt + * @param pRTC : The base address of RTC block + * @return Alarm event time + */ +STATIC INLINE uint32_t Chip_RTC_GetAlarm(LPC_RTC_T *pRTC) +{ + return pRTC->MATCH; +} + +/** + * @brief Set RTC match count for 1 second timer count + * @param pRTC : The base address of RTC block + * @param count : Initial count to set + * @return Nothing + * @note Only write to this register when the RTC_CTRL_RTC_EN bit in + * the CTRL Register is 0. The counter increments one second + * after the RTC_CTRL_RTC_EN bit is set. + */ +STATIC INLINE void Chip_RTC_SetCount(LPC_RTC_T *pRTC, uint32_t count) +{ + pRTC->COUNT = count; +} + +/** + * @brief Get current RTC 1 second timer count + * @param pRTC : The base address of RTC block + * @return current RTC 1 second timer count + */ +STATIC INLINE uint32_t Chip_RTC_GetCount(LPC_RTC_T *pRTC) +{ + return pRTC->COUNT; +} + +/** + * @brief Set RTC wake count countdown value (in mS ticks) + * @param pRTC : The base address of RTC block + * @param count : wakeup time in milliSeconds + * @return Nothing + * @note A write pre-loads a start count value into the wake-up + * timer and initializes a count-down sequence. + */ +STATIC INLINE void Chip_RTC_SetWake(LPC_RTC_T *pRTC, uint16_t count) +{ + pRTC->WAKE = count; +} + +/** + * @brief Get RTC wake count countdown value + * @param pRTC : The base address of RTC block + * @return current RTC wake count countdown value (in mS) + */ +STATIC INLINE uint16_t Chip_RTC_GetWake(LPC_RTC_T *pRTC) +{ + return pRTC->WAKE; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RTC_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/sct_15xx.h b/lpc_chip_15xx/inc/sct_15xx.h new file mode 100644 index 0000000..b93488e --- /dev/null +++ b/lpc_chip_15xx/inc/sct_15xx.h @@ -0,0 +1,462 @@ +/* + * @brief LPC15XX State Configurable Timer (SCT) Chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SCT_15XX_H_ +#define __SCT_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SCT_15XX CHIP: LPC15XX State Configurable Timer driver + * @ingroup Chip_15XX_Drivers + * @{ + */ + +/* + * @brief SCT Module configuration + */ +#define CONFIG_SCT_nEV (16) /*!< Number of events */ +#define CONFIG_SCT_nRG (15) /*!< Number of match/compare registers */ +#define CONFIG_SCT_nOU (10) /*!< Number of outputs */ +#define CONFIG_SCT_nFR (6) /*!< Number of fractional match reload register */ + +/** + * @brief State Configurable Timer register block structure + */ +typedef struct { + __IO uint32_t CONFIG; /*!< Configuration Register */ + union { + __IO uint32_t CTRL_U; /*!< Control Register */ + struct { + __IO uint16_t CTRL_L; /*!< Low control register */ + __IO uint16_t CTRL_H; /*!< High control register */ + }; + + }; + + union { + __IO uint32_t LIMIT; /*!< limit Register */ + struct { + __IO uint16_t LIMIT_L; /*!< limit register for counter L */ + __IO uint16_t LIMIT_H; /*!< limit register for counter H */ + }; + + }; + + union { + __IO uint32_t HALT; /*!< Halt Register */ + struct { + __IO uint16_t HALT_L; /*!< halt register for counter L */ + __IO uint16_t HALT_H; /*!< halt register for counter H */ + }; + + }; + + union { + __IO uint32_t STOP; /*!< Stop Register */ + struct { + __IO uint16_t STOP_L; /*!< stop register for counter L */ + __IO uint16_t STOP_H; /*!< stop register for counter H */ + }; + + }; + + union { + __IO uint32_t START; /*!< start Register */ + struct { + __IO uint16_t START_L; /*!< start register for counter L */ + __IO uint16_t START_H; /*!< start register for counter H */ + }; + + }; + + union { + __IO uint32_t DITHER; /*!< start Register */ + struct { + __IO uint16_t DITHER_L; /*!< start register for counter L */ + __IO uint16_t DITHER_H; /*!< start register for counter H */ + }; + + }; + + uint32_t RESERVED1[9]; /*!< 0x03C reserved */ + union { + __IO uint32_t COUNT_U; /*!< counter register */ + struct { + __IO uint16_t COUNT_L; /*!< counter register for counter L */ + __IO uint16_t COUNT_H; /*!< counter register for counter H */ + }; + + }; + + union { + __IO uint32_t STATE; /*!< State register */ + struct { + __IO uint16_t STATE_L; /*!< state register for counter L */ + __IO uint16_t STATE_H; /*!< state register for counter H */ + }; + + }; + + __I uint32_t INPUT; /*!< input register */ + union { + __IO uint32_t REGMODE; /*!< RegMode register */ + struct { + __IO uint16_t REGMODE_L; /*!< match - capture registers mode register L */ + __IO uint16_t REGMODE_H; /*!< match - capture registers mode register H */ + }; + + }; + + __IO uint32_t OUTPUT; /*!< output register */ + __IO uint32_t OUTPUTDIRCTRL; /*!< output counter direction Control Register */ + __IO uint32_t RES; /*!< conflict resolution register */ + __IO uint32_t DMA0REQUEST; /*!< DMA0 Request Register */ + __IO uint32_t DMA1REQUEST; /*!< DMA1 Request Register */ + uint32_t RESERVED2[35]; + __IO uint32_t EVEN; /*!< event enable register */ + __IO uint32_t EVFLAG; /*!< event flag register */ + __IO uint32_t CONEN; /*!< conflict enable register */ + __IO uint32_t CONFLAG; /*!< conflict flag register */ + union { + __IO union { /*!< ... Match / Capture value */ + uint32_t U; /*!< SCTMATCH[i].U Unified 32-bit register */ + struct { + uint16_t L; /*!< SCTMATCH[i].L Access to L value */ + uint16_t H; /*!< SCTMATCH[i].H Access to H value */ + }; + + } MATCH[CONFIG_SCT_nRG]; + + __I union { + uint32_t U; /*!< SCTCAP[i].U Unified 32-bit register */ + struct { + uint16_t L; /*!< SCTCAP[i].L Access to L value */ + uint16_t H; /*!< SCTCAP[i].H Access to H value */ + }; + + } CAP[CONFIG_SCT_nRG]; + + }; + + uint32_t RESERVED3[64 - CONFIG_SCT_nRG]; /*!< ...-0x1FC reserved */ + + union { + __IO union { /*!< ... Match reload value */ + uint32_t U; /*!< MATCHREL[i].U Unified 32-bit register */ + struct { + uint16_t L; /*!< MATCHREL[i].L Access to L value */ + uint16_t H; /*!< MATCHREL[i].H Access to H value */ + }; + + } MATCHREL[CONFIG_SCT_nRG]; + + __IO union { + uint32_t U; /*!< CAPCTRL[i].U Unified 32-bit register */ + struct { + uint16_t L; /*!< CAPCTRL[i].L Access to L value */ + uint16_t H; /*!< CAPCTRL[i].H Access to H value */ + }; + + } CAPCTRL[CONFIG_SCT_nRG]; + + }; + + __IO union { + uint32_t U; /*!< CAPCTRL[i].U Unified 32-bit register */ + struct { + uint16_t L; /*!< CAPCTRL[i].L Access to L value */ + uint16_t H; /*!< CAPCTRL[i].H Access to H value */ + }; + + } FRACMATREL[CONFIG_SCT_nFR]; + + uint32_t RESERVED4[64 - CONFIG_SCT_nRG - CONFIG_SCT_nFR]; /*!< ...-0x2FC reserved */ + + __IO struct { /*!< SCTEVENT[i].STATE / SCTEVENT[i].CTRL*/ + uint32_t STATE; /*!< Event State Register */ + uint32_t CTRL; /*!< Event Control Register */ + } EVENT[CONFIG_SCT_nEV]; + + uint32_t RESERVED9[128 - 2 * CONFIG_SCT_nEV]; /*!< ...-0x4FC reserved */ + __IO struct { /*!< SCTOUT[i].SET / SCTOUT[i].CLR */ + uint32_t SET; /*!< Output n Set Register */ + uint32_t CLR; /*!< Output n Clear Register */ + } OUT[CONFIG_SCT_nOU]; + +} LPC_SCT_T; + +/* + * @brief Macro defines for SCT configuration register + */ +#define SCT_CONFIG_16BIT_COUNTER 0x00000000 /*!< Operate as 2 16-bit counters */ +#define SCT_CONFIG_32BIT_COUNTER 0x00000001 /*!< Operate as 1 32-bit counter */ + +#define SCT_CONFIG_CLKMODE_BUSCLK (0x0 << 1) /*!< Bus clock */ +#define SCT_CONFIG_CLKMODE_SCTCLK (0x1 << 1) /*!< SCT clock */ +#define SCT_CONFIG_CLKMODE_INCLK (0x2 << 1) /*!< Input clock selected in CLKSEL field */ +#define SCT_CONFIG_CLKMODE_INEDGECLK (0x3 << 1) /*!< Input clock edge selected in CLKSEL field */ + +#define SCT_CONFIG_NORELOADL_U (0x1 << 7) /*!< Operate as 1 32-bit counter */ +#define SCT_CONFIG_NORELOADH (0x1 << 8) /*!< Operate as 1 32-bit counter */ +#define SCT_CONFIG_AUTOLIMIT_L (0x1 << 17) /*!< Limits counter(L) based on MATCH0 */ +#define SCT_CONFIG_AUTOLIMIT_H (0x1 << 18) /*!< Limits counter(L) based on MATCH0 */ + + +/* + * @brief Macro defines for SCT control register + */ +#define COUNTUP_TO_LIMIT_THEN_CLEAR_TO_ZERO 0 /*!< Direction for low or unified counter */ +#define COUNTUP_TO LIMIT_THEN_COUNTDOWN_TO_ZERO 1 + +#define SCT_CTRL_STOP_L (1 << 1) /*!< Stop low counter */ +#define SCT_CTRL_HALT_L (1 << 2) /*!< Halt low counter */ +#define SCT_CTRL_CLRCTR_L (1 << 3) /*!< Clear low or unified counter */ +#define SCT_CTRL_BIDIR_L(x) (((x) & 0x01) << 4) /*!< Bidirectional bit */ +#define SCT_CTRL_PRE_L(x) (((x) & 0xFF) << 5) /*!< Prescale clock for low or unified counter */ + +#define COUNTUP_TO_LIMIT_THEN_CLEAR_TO_ZERO 0 /*!< Direction for high counter */ +#define COUNTUP_TO LIMIT_THEN_COUNTDOWN_TO_ZERO 1 +#define SCT_CTRL_STOP_H (1 << 17) /*!< Stop high counter */ +#define SCT_CTRL_HALT_H (1 << 18) /*!< Halt high counter */ +#define SCT_CTRL_CLRCTR_H (1 << 19) /*!< Clear high counter */ +#define SCT_CTRL_BIDIR_H(x) (((x) & 0x01) << 20) +#define SCT_CTRL_PRE_H(x) (((x) & 0xFF) << 21) /*!< Prescale clock for high counter */ + +/* + * @brief Macro defines for SCT Conflict resolution register + */ +#define SCT_RES_NOCHANGE (0) +#define SCT_RES_SET_OUTPUT (1) +#define SCT_RES_CLEAR_OUTPUT (2) +#define SCT_RES_TOGGLE_OUTPUT (3) + +/** + * SCT Match register values enum + */ +typedef enum CHIP_SCT_MATCH_REG { + SCT_MATCH_0 = 0, /*!< SCT Match register 0 */ + SCT_MATCH_1 = 1, /*!< SCT Match register 1 */ + SCT_MATCH_2 = 2, /*!< SCT Match register 2 */ + SCT_MATCH_3 = 3, /*!< SCT Match register 3 */ + SCT_MATCH_4 = 4 /*!< SCT Match register 4 */ +} CHIP_SCT_MATCH_REG_T; + +/** + * SCT Event values enum + */ +typedef enum CHIP_SCT_EVENT { + SCT_EVT_0 = (1 << 0), /*!< Event 0 */ + SCT_EVT_1 = (1 << 1), /*!< Event 1 */ + SCT_EVT_2 = (1 << 2), /*!< Event 2 */ + SCT_EVT_3 = (1 << 3), /*!< Event 3 */ + SCT_EVT_4 = (1 << 4), /*!< Event 4 */ + SCT_EVT_5 = (1 << 5) /*!< Event 5 */ +} CHIP_SCT_EVENT_T; + +/** + * @brief Configures the State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param value : The 32-bit CONFIG register value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_Config(LPC_SCT_T *pSCT, uint32_t value) +{ + pSCT->CONFIG = value; +} + +/** + * @brief Set or Clear the Control register + * @param pSCT : Pointer to SCT register block + * @param value : SCT Control register value + * @param ena : ENABLE - To set the fields specified by value + * : DISABLE - To clear the field specified by value + * @return Nothing + * Set or clear the control register bits as specified by the \a value + * parameter. If \a ena is set to ENABLE, the mentioned register fields + * will be set. If \a ena is set to DISABLE, the mentioned register + * fields will be cleared + */ +void Chip_SCT_SetClrControl(LPC_SCT_T *pSCT, uint32_t value, FunctionalState ena); + +/** + * @brief Set the conflict resolution + * @param pSCT : Pointer to SCT register block + * @param outnum : Output number + * @param value : Output value + * - SCT_RES_NOCHANGE :No change + * - SCT_RES_SET_OUTPUT :Set output + * - SCT_RES_CLEAR_OUTPUT :Clear output + * - SCT_RES_TOGGLE_OUTPUT :Toggle output + * : SCT_RES_NOCHANGE + * : DISABLE - To clear the field specified by value + * @return Nothing + * Set conflict resolution for the output \a outnum + */ +void Chip_SCT_SetConflictResolution(LPC_SCT_T *pSCT, uint8_t outnum, uint8_t value); + +/** + * @brief Set unified count value in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param count : The 32-bit count value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetCount(LPC_SCT_T *pSCT, uint32_t count) +{ + pSCT->COUNT_U = count; +} + +/** + * @brief Set lower count value in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param count : The 16-bit count value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetCountL(LPC_SCT_T *pSCT, uint16_t count) +{ + pSCT->COUNT_L = count; +} + +/** + * @brief Set higher count value in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param count : The 16-bit count value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetCountH(LPC_SCT_T *pSCT, uint16_t count) +{ + pSCT->COUNT_H = count; +} + +/** + * @brief Set unified match count value in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param n : Match register value + * @param value : The 32-bit match count value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetMatchCount(LPC_SCT_T *pSCT, CHIP_SCT_MATCH_REG_T n, uint32_t value) +{ + pSCT->MATCH[n].U = value; +} + +/** + * @brief Set unified match reload count value in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param n : Match register value + * @param value : The 32-bit match count reload value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetMatchReload(LPC_SCT_T *pSCT, CHIP_SCT_MATCH_REG_T n, uint32_t value) +{ + pSCT->MATCHREL[n].U = value; +} + +/** + * @brief Enable the interrupt for the specified event in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param evt : Event value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_EnableEventInt(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt) +{ + pSCT->EVEN |= evt; +} + +/** + * @brief Disable the interrupt for the specified event in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param evt : Event value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_DisableEventInt(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt) +{ + pSCT->EVEN &= ~(evt); +} + +/** + * @brief Clear the specified event flag in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param evt : Event value + * @return Nothing + */ +STATIC INLINE void Chip_SCT_ClearEventFlag(LPC_SCT_T *pSCT, CHIP_SCT_EVENT_T evt) +{ + pSCT->EVFLAG |= evt; +} + +/** + * @brief Set control register in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param value : Value (ORed value of SCT_CTRL_* bits) + * @return Nothing + */ +STATIC INLINE void Chip_SCT_SetControl(LPC_SCT_T *pSCT, uint32_t value) +{ + pSCT->CTRL_U |= value; +} + +/** + * @brief Clear control register in State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @param value : Value (ORed value of SCT_CTRL_* bits) + * @return Nothing + */ +STATIC INLINE void Chip_SCT_ClearControl(LPC_SCT_T *pSCT, uint32_t value) +{ + pSCT->CTRL_U &= ~(value); +} + +/** + * @brief Initializes the State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @return Nothing + */ +void Chip_SCT_Init(LPC_SCT_T *pSCT); + +/** + * @brief Deinitializes the State Configurable Timer + * @param pSCT : The base of SCT peripheral on the chip + * @return Nothing + */ +void Chip_SCT_DeInit(LPC_SCT_T *pSCT); + +/** + * @} + */ + +#ifdef __cplusplus +} + +#endif + +#endif /* __SCT_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/sct_pwm_15xx.h b/lpc_chip_15xx/inc/sct_pwm_15xx.h new file mode 100644 index 0000000..2b45357 --- /dev/null +++ b/lpc_chip_15xx/inc/sct_pwm_15xx.h @@ -0,0 +1,178 @@ +/* + * @brief LPC15xx State Configurable Timer (SCT/PWM) Chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SCT_PWM_15XX_H_ +#define __SCT_PWM_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SCT_PWM_15XX CHIP: LPC15XX State Configurable Timer PWM driver + * + * For more information on how to use the driver please visit the FAQ page at + * + * www.lpcware.com + * + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief Get number of ticks per PWM cycle + * @param pSCT : The base of SCT peripheral on the chip + * @return Number ot ticks that will be counted per cycle + * @note Return value of this function will be vaild only + * after calling Chip_SCTPWM_SetRate() + */ +STATIC INLINE uint32_t Chip_SCTPWM_GetTicksPerCycle(LPC_SCT_T *pSCT) +{ + return pSCT->MATCHREL[0].U; +} + +/** + * @brief Converts a percentage to ticks + * @param pSCT : The base of SCT peripheral on the chip + * @param percent : Percentage to convert (0 - 100) + * @return Number ot ticks corresponding to given percentage + * @note Do not use this function when using very low + * pwm rate (like 100Hz or less), on a chip that has + * very high frequency as the calculation might + * cause integer overflow + */ +STATIC INLINE uint32_t Chip_SCTPWM_PercentageToTicks(LPC_SCT_T *pSCT, uint8_t percent) +{ + return (Chip_SCTPWM_GetTicksPerCycle(pSCT) * percent) / 100; +} + +/** + * @brief Get number of ticks on per PWM cycle + * @param pSCT : The base of SCT peripheral on the chip + * @param index : Index of the PWM 1 to N (see notes) + * @return Number ot ticks for which the output will be ON per cycle + * @note @a index will be 1 to N where N is the "Number of + * match registers available in the SCT - 1" or + * "Number of OUTPUT pins available in the SCT" whichever + * is minimum. + */ +STATIC INLINE uint32_t Chip_SCTPWM_GetDutyCycle(LPC_SCT_T *pSCT, uint8_t index) +{ + return pSCT->MATCHREL[index].U; +} + +/** + * @brief Get number of ticks on per PWM cycle + * @param pSCT : The base of SCT peripheral on the chip + * @param index : Index of the PWM 1 to N (see notes) + * @param ticks : Number of ticks the output should say ON + * @return None + * @note @a index will be 1 to N where N is the "Number of + * match registers available in the SCT - 1" or + * "Number of OUTPUT pins available in the SCT" whichever + * is minimum. The new duty cycle will be effective only + * after completion of current PWM cycle. + */ +STATIC INLINE void Chip_SCTPWM_SetDutyCycle(LPC_SCT_T *pSCT, uint8_t index, uint32_t ticks) +{ + Chip_SCT_SetMatchReload(pSCT, (CHIP_SCT_MATCH_REG_T)index, ticks); +} + +/** + * @brief Initialize the SCT/PWM clock and reset + * @param pSCT : The base of SCT peripheral on the chip + * @return None + */ +STATIC INLINE void Chip_SCTPWM_Init(LPC_SCT_T *pSCT) +{ + Chip_SCT_Init(pSCT); +} + +/** + * @brief Start the SCT PWM + * @param pSCT : The base of SCT peripheral on the chip + * @return None + * @note This function must be called after all the + * configuration is completed. Do not call Chip_SCTPWM_SetRate() + * or Chip_SCTPWM_SetOutPin() after the SCT/PWM is started. Use + * Chip_SCTPWM_Stop() to stop the SCT/PWM before reconfiguring, + * Chip_SCTPWM_SetDutyCycle() can be called when the SCT/PWM is + * running to change the DutyCycle. + */ +STATIC INLINE void Chip_SCTPWM_Start(LPC_SCT_T *pSCT) +{ + Chip_SCT_ClearControl(pSCT, SCT_CTRL_HALT_L | SCT_CTRL_HALT_H); +} + +/** + * @brief Stop the SCT PWM + * @param pSCT : The base of SCT peripheral on the chip + * @return None + */ +STATIC INLINE void Chip_SCTPWM_Stop(LPC_SCT_T *pSCT) +{ + /* Stop SCT */ + Chip_SCT_SetControl(pSCT, SCT_CTRL_HALT_L | SCT_CTRL_HALT_H); + + /* Clear the counter */ + Chip_SCT_SetControl(pSCT, SCT_CTRL_CLRCTR_L | SCT_CTRL_CLRCTR_H); +} + +/** + * @brief Sets the frequency of the generated PWM wave + * @param pSCT : The base of SCT peripheral on the chip + * @param freq : Frequency in Hz + * @return None + */ +void Chip_SCTPWM_SetRate(LPC_SCT_T *pSCT, uint32_t freq); + +/** + * @brief Setup the OUTPUT pin and associate it with an index + * @param pSCT : The base of the SCT peripheral on the chip + * @param index : Index of PWM 1 to N (see notes) + * @param pin : COUT pin to be associated with the index + * @return None + * @note @a index will be 1 to N where N is the "Number of + * match registers available in the SCT - 1" or + * "Number of OUTPUT pins available in the SCT" whichever + * is minimum. + */ +void Chip_SCTPWM_SetOutPin(LPC_SCT_T *pSCT, uint8_t index, uint8_t pin); + +/** + * @} + */ + +#ifdef __cplusplus +} + +#endif + +#endif /* __SCT_PWM_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/sctipu_15xx.h b/lpc_chip_15xx/inc/sctipu_15xx.h new file mode 100644 index 0000000..d39bd6b --- /dev/null +++ b/lpc_chip_15xx/inc/sctipu_15xx.h @@ -0,0 +1,165 @@ +/* + * @brief LPC15xx SCTIPU driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SCTIPU_15XX_H_ +#define __SCTIPU_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SCTIPU_15XX CHIP: LPC15xx SCT Input Processing Unit (SCTIPU) driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15XX SCTIPU abort enable/source register block structure + */ +typedef struct { /*!< LPC15XX abort enable/source structure */ + __IO uint32_t ABORT_ENABLE; /*!< SCTIPU abort enable register */ + __IO uint32_t ABORT_SOURCE; /*!< SCTIPU abort source register */ + __I uint32_t RESERVED[6]; +} LPC_SCTIPU_ABT_T; + +/** + * @brief LPC15XX SCTIPU register block structure + */ +typedef struct { /*!< LPC15XX SCTIPU Structure */ + __IO uint32_t SAMPLE_CTRL; /*!< SCTIPU sample control register */ + __I uint32_t RESERVED[7]; + LPC_SCTIPU_ABT_T ABORT[4]; /*!< SCTIPU abort enable/source registers */ +} LPC_SCTIPU_T; + +/** + * @brief Initialize the SCTIPU + * @return Nothing + * @note Must be called prior to any other SCTIPU function. Sets up clocking and + * initial SCTIPU states. + */ +STATIC INLINE void Chip_SCTIPU_Init(void) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SCTIPU); + Chip_SYSCTL_PeriphReset(RESET_SCTIPU); +} + +/** + * @brief De-Initialize the SCTIPU + * @return Nothing + */ +STATIC INLINE void Chip_SCTIPU_DeInit(void) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SCTIPU); +} + +/** + * SCTIPU sample control register bit definitions + */ +#define SCTIPU_CTRL_INSEL(ch, src) ((src) << (ch)) /*!< Select SCTIPU sample (src) source for output channel ch */ +#define SCTIPU_CTRL_INSELMASK(ch) (1 << (ch)) /*!< SCTIPU sample (src) source mask for output channel ch */ +#define SCTIPU_CTRL_SAMPENA (0) /*!< Selects Sample_Enable_A as the latch/sample-enable control for the Sample_Output latch */ +#define SCTIPU_CTRL_SAMPENB (1) /*!< Selects Sample_Enable_A as the latch/sample-enable control for the Sample_Output latch */ +#define SCTIPU_CTRL_SAMPENC (2) /*!< Selects Sample_Enable_A as the latch/sample-enable control for the Sample_Output latch */ +#define SCTIPU_CTRL_SAMPEND (3) /*!< Selects Sample_Enable_A as the latch/sample-enable control for the Sample_Output latch */ +#define SCTIPU_CTRL_SAMPENDSEL(ch, src) ((src) << (2 + (ch * 2))) /*!< Select SCTIPU sample (src) source for output channel ch */ +#define SCTIPU_CTRL_SAMPENDMASK(ch) (0x3 << (2 + (ch * 2))) /*!< SCTIPU sample (src) source mask for output channel ch */ +#define SCTIPU_CTRL_LATCHENSEL(ch, ltc) ((ltc) << (12 + ch)) /*!< Select SCTIPU latched mode for output channel ch */ +#define SCTIPU_CTRL_LATCHENMASK(ch) (1 << (12 + ch)) /*!< SCTIPU latched mode mask for output channel ch */ +#define SCTIPU_RESERVED_BITS 0xFFFF0000 + +/** + * @brief Sets up an configuration and input source for a SCTIPU output channel + * @param ch : SCTIPU channel, 0-3 + * @param useb : 0 to use SAMPLE_IN_A for the channel, or 1 for SAMPLE_IN_B + * @param sampIn : Sample enable input, must be SCTIPU_CTRL_SAMPENA via SCTIPU_CTRL_SAMPEND + * @param useLatch : 0 to transparent mode. for the channel, or 1 for latched mode + * @return Nothing + * @note Example: Chip_SCTIPU_ConfigSample(0, true, SCTIPU_CTRL_SAMPENC, true); + */ +void Chip_SCTIPU_ConfigSample(uint8_t ch, uint8_t useb, uint8_t sampIn, uint8_t useLatch); + +/** + * SCTIPU abort enable sources + */ +#define SCTIPU_ABTENA_SCT_ABORT0 (1 << 0) /*!< Enable abort source SCT_ABORT0. Select pin from switch matrix */ +#define SCTIPU_ABTENA_SCT_ABORT1 (1 << 1) /*!< Enable abort source SCT_ABORT1. Select pin from switch matrix */ +#define SCTIPU_ABTENA_SCT0_OUT9 (1 << 2) /*!< Enable abort source SCT0_OUT9 */ +#define SCTIPU_ABTENA_ADC0_THCMP_IRQ (1 << 3) /*!< Enable abort source ADC0_THCMP_IRQ */ +#define SCTIPU_ABTENA_ADC1_THCMP_IRQ (1 << 4) /*!< Enable abort source ADC1_THCMP_IRQ */ +#define SCTIPU_ABTENA_ACMP0_O (1 << 5) /*!< Enable abort source ACMP0_O */ +#define SCTIPU_ABTENA_ACMP1_O (1 << 6) /*!< Enable abort source ACMP1_O */ +#define SCTIPU_ABTENA_ACMP2_O (1 << 7) /*!< Enable abort source ACMP2_O */ +#define SCTIPU_ABTENA_ACMP3_O (1 << 8) /*!< Enable abort source ACMP3_O */ + +/** + * @brief Selects multiple abort input enables that will be enabled to contribute to the ORed output + * @param ch : SCTIPU channel, 0-3 + * @param srcAbort : Or'ed values of SCTIPU_ABTENA_* defintions used for OR'ed abort enables + * @return Nothing + * @note Example: Chip_SCTIPU_ConfigSample(0, SCTIPU_ABTENA_ACMP0_O | SCTIPU_ABTENA_ACMP1_O);
+ */ +STATIC INLINE void Chip_SCTIPU_AbortInputEnable(uint8_t ch, uint32_t srcAbort) +{ + LPC_SCTIPU->ABORT[ch].ABORT_ENABLE = srcAbort; +} + +/** + * @brief Gets the activated SCT abort sources + * @param ch : SCTIPU channel, 0-3 + * @return Nothing + * @note To determine if a source is active, mask the return value with a + * SCTIPU_ABTENA_* definition. + */ +STATIC INLINE uint32_t Chip_SCTIPU_GetActiveAbortSrc(uint8_t ch) +{ + return LPC_SCTIPU->ABORT[ch].ABORT_SOURCE; +} + +/** + * @brief Clears activated SCT abort sources + * @param ch : SCTIPU channel, 0-3 + * @param srcClear : Or'ed values of SCTIPU_ABTENA_* defintions used for clearing activated states + * @return Nothing + */ +STATIC INLINE void Chip_SCTIPU_ClearActiveAbortSrc(uint8_t ch, uint32_t srcClear) +{ + LPC_SCTIPU->ABORT[ch].ABORT_SOURCE = srcClear; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SCTIPU_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/spi_15xx.h b/lpc_chip_15xx/inc/spi_15xx.h new file mode 100644 index 0000000..01ba963 --- /dev/null +++ b/lpc_chip_15xx/inc/spi_15xx.h @@ -0,0 +1,634 @@ +/* + * @brief LPC15xx SPI driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SPI_15XX_H_ +#define __SPI_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SPI_15XX CHIP: LPC15xx SPI driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ +/** + * @brief SPI register block structure + */ +typedef struct { /*!< SPI Structure */ + __IO uint32_t CFG; /*!< SPI Configuration register*/ + __IO uint32_t DLY; /*!< SPI Delay register*/ + __IO uint32_t STAT; /*!< SPI Status. register*/ + __IO uint32_t INTENSET; /*!< SPI Interrupt Enable.Set register*/ + __O uint32_t INTENCLR; /*!< SPI Interrupt Enable Clear. register*/ + __I uint32_t RXDAT; /*!< SPI Receive Data register*/ + __IO uint32_t TXDATCTL; /*!< SPI Transmit Data with Control register*/ + __IO uint32_t TXDAT; /*!< SPI Transmit Data register*/ + __IO uint32_t TXCTRL; /*!< SPI Transmit Control register*/ + __IO uint32_t DIV; /*!< SPI clock Divider register*/ + __I uint32_t INTSTAT; /*!< SPI Interrupt Status register*/ +} LPC_SPI_T; + +/** + * Macro defines for SPI Configuration register + */ +/* SPI CFG Register BitMask */ +#define SPI_CFG_BITMASK ((uint32_t) 0xFBD) +/** SPI enable */ +#define SPI_CFG_SPI_EN ((uint32_t) (1 << 0)) +/** SPI Slave Mode Select */ +#define SPI_CFG_SLAVE_EN ((uint32_t) (0 << 2)) +/** SPI Master Mode Select */ +#define SPI_CFG_MASTER_EN ((uint32_t) (1 << 2)) +/** SPI MSB First mode enable */ +#define SPI_CFG_MSB_FIRST_EN ((uint32_t) (0 << 3)) /*Data will be transmitted and received in standard order (MSB first).*/ +/** SPI LSB First mode enable */ +#define SPI_CFG_LSB_FIRST_EN ((uint32_t) (1 << 3))/*Data will be transmitted and received in reverse order (LSB first).*/ +/** SPI Clock Phase Select*/ +#define SPI_CFG_CPHA_FIRST ((uint32_t) (0 << 4)) /*Capture data on the first edge, Change data on the following edge*/ +#define SPI_CFG_CPHA_SECOND ((uint32_t) (1 << 4)) /*Change data on the first edge, Capture data on the following edge*/ +/** SPI Clock Polarity Select*/ +#define SPI_CFG_CPOL_LO ((uint32_t) (0 << 5)) /* The rest state of the clock (between frames) is low.*/ +#define SPI_CFG_CPOL_HI ((uint32_t) (1 << 5)) /* The rest state of the clock (between frames) is high.*/ +/** SPI control 1 loopback mode enable */ +#define SPI_CFG_LBM_EN ((uint32_t) (1 << 7)) +/** SPI SSEL0 Polarity Select*/ +#define SPI_CFG_SPOL0_LO ((uint32_t) (0 << 8)) /* SSEL0 is active Low */ +#define SPI_CFG_SPOL0_HI ((uint32_t) (1 << 8)) /* SSEL0 is active High */ +/** SPI SSEL1 Polarity Select*/ +#define SPI_CFG_SPOL1_LO ((uint32_t) (0 << 9)) /* SSEL1 is active Low */ +#define SPI_CFG_SPOL1_HI ((uint32_t) (1 << 9)) /* SSEL1 is active High */ +/** SPI SSEL2 Polarity Select*/ +/** Note that SSEL2, SSEL3 is only available on SPI0 not on SPI1 */ +#define SPI_CFG_SPOL2_LO ((uint32_t) (0 << 10)) /* SSEL2 is active Low */ +#define SPI_CFG_SPOL2_HI ((uint32_t) (1 << 10)) /* SSEL2 is active High */ +/** SPI SSEL3 Polarity Select*/ +#define SPI_CFG_SPOL3_LO ((uint32_t) (0 << 11)) /* SSEL3 is active Low */ +#define SPI_CFG_SPOL3_HI ((uint32_t) (1 << 11)) /* SSEL3 is active High */ + +/** + * Macro defines for SPI Delay register + */ +/** SPI DLY Register Mask */ +#define SPI_DLY_BITMASK ((uint32_t) 0xFFFF) +/** Controls the amount of time between SSEL assertion and the beginning of a data frame. */ +#define SPI_DLY_PRE_DELAY(n) ((uint32_t) ((n) & 0x0F)) /* Time Unit: SPI clock time */ +/** Controls the amount of time between the end of a data frame and SSEL deassertion. */ +#define SPI_DLY_POST_DELAY(n) ((uint32_t) (((n) & 0x0F) << 4)) /* Time Unit: SPI clock time */ +/** Controls the minimum amount of time between adjacent data frames. */ +#define SPI_DLY_FRAME_DELAY(n) ((uint32_t) (((n) & 0x0F) << 8)) /* Time Unit: SPI clock time */ +/** Controls the minimum amount of time that the SSEL is deasserted between transfers. */ +#define SPI_DLY_TRANSFER_DELAY(n) ((uint32_t) (((n) & 0x0F) << 12)) /* Time Unit: SPI clock time */ + +/** + * Macro defines for SPI Status register + */ +/* SPI STAT Register BitMask */ +#define SPI_STAT_BITMASK ((uint32_t) 0x1FF) +/* Receiver Ready Flag */ +#define SPI_STAT_RXRDY ((uint32_t) (1 << 0)) /* Data is ready for read */ +/* Transmitter Ready Flag */ +#define SPI_STAT_TXRDY ((uint32_t) (1 << 1)) /* Data may be written to transmit buffer */ +/* Receiver Overrun interrupt flag */ +#define SPI_STAT_RXOV ((uint32_t) (1 << 2)) /* Data comes while receiver buffer is in used */ +/* Transmitter Underrun interrupt flag (In Slave Mode only) */ +#define SPI_STAT_TXUR ((uint32_t) (1 << 3)) /* There is no data to be sent in the next input clock */ +/* Slave Select Assert */ +#define SPI_STAT_SSA ((uint32_t) (1 << 4)) /* There is SSEL transition from deasserted to asserted */ +/* Slave Select Deassert */ +#define SPI_STAT_SSD ((uint32_t) (1 << 5)) /* There is SSEL transition from asserted to deasserted */ +/* Stalled status flag */ +#define SPI_STAT_STALLED ((uint32_t) (1 << 6)) /* SPI is currently in a stall condition. */ +/* End Transfer flag. */ +#define SPI_STAT_EOT ((uint32_t) (1 << 7)) /* The current frame is the last frame of the current transfer. */ +/* Master Idle status flag. */ +#define SPI_STAT_MSTIDLE ((uint32_t) (1 << 8)) /* SPI master function is fully idle. */ + +/* Clear RXOV Flag */ +#define SPI_STAT_CLR_RXOV ((uint32_t) (1 << 2)) +/* Clear TXUR Flag */ +#define SPI_STAT_CLR_TXUR ((uint32_t) (1 << 3)) +/* Clear SSA Flag */ +#define SPI_STAT_CLR_SSA ((uint32_t) (1 << 4)) +/* Clear SSD Flag */ +#define SPI_STAT_CLR_SSD ((uint32_t) (1 << 5)) +/*Force an end to the current transfer */ +#define SPI_STAT_FORCE_EOT ((uint32_t) (1 << 7)) + +/** + * Macro defines for SPI Interrupt Enable read and Set register + */ +/* SPI INTENSET Register BitMask */ +#define SPI_INTENSET_BITMASK ((uint32_t) 0x3F) +/** Enable Interrupt when receiver data is available */ +#define SPI_INTENSET_RXRDYEN ((uint32_t) (1 << 0)) +/** Enable Interrupt when the transmitter holding register is available. */ +#define SPI_INTENSET_TXRDYEN ((uint32_t) (1 << 1)) +/** Enable Interrupt when a receiver overrun occurs */ +#define SPI_INTENSET_RXOVEN ((uint32_t) (1 << 2)) +/** Enable Interrupt when a transmitter underrun occurs (In Slave Mode Only)*/ +#define SPI_INTENSET_TXUREN ((uint32_t) (1 << 3)) +/** Enable Interrupt when the Slave Select is asserted.*/ +#define SPI_INTENSET_SSAEN ((uint32_t) (1 << 4)) +/** Enable Interrupt when the Slave Select is deasserted..*/ +#define SPI_INTENSET_SSDEN ((uint32_t) (1 << 5)) + +/** + * Macro defines for SPI Interrupt Enable Clear register + */ +/* SPI INTENCLR Register BitMask */ +#define SPI_INTENCLR_BITMASK ((uint32_t) 0x3F) +/** Disable Interrupt when receiver data is available */ +#define SPI_INTENCLR_RXRDYEN ((uint32_t) (1 << 0)) +/** Disable Interrupt when the transmitter holding register is available. */ +#define SPI_INTENCLR_TXRDYEN ((uint32_t) (1 << 1)) +/** Disable Interrupt when a receiver overrun occurs */ +#define SPI_INTENCLR_RXOVEN ((uint32_t) (1 << 2)) +/** Disable Interrupt when a transmitter underrun occurs (In Slave Mode Only)*/ +#define SPI_INTENCLR_TXUREN ((uint32_t) (1 << 3)) +/** Disable Interrupt when the Slave Select is asserted.*/ +#define SPI_INTENCLR_SSAEN ((uint32_t) (1 << 4)) +/** Disable Interrupt when the Slave Select is deasserted..*/ +#define SPI_INTENCLR_SSDEN ((uint32_t) (1 << 5)) + +/** + * Macro defines for SPI Receiver Data register + */ +/* SPI RXDAT Register BitMask */ +#define SPI_RXDAT_BITMASK ((uint32_t) 0x1FFFFF) +/** Receiver Data */ +#define SPI_RXDAT_DATA(n) ((uint32_t) ((n) & 0xFFFF)) +/** The state of SSEL0 pin */ +#define SPI_RXDAT_RXSSEL0_ACTIVE ((uint32_t) (0 << 16)) /* SSEL0 is in active state */ +#define SPI_RXDAT_RXSSEL0_INACTIVE ((uint32_t) (1 << 16)) /* SSEL0 is in inactive state */ +#define SPI_RXDAT_RXSSEL0_FLAG ((uint32_t) (1 << 16)) /* SSEL0 Rx Flag */ +/** The state of SSEL1 pin */ +#define SPI_RXDAT_RXSSEL1_ACTIVE ((uint32_t) (0 << 17)) /* SSEL1 is in active state */ +#define SPI_RXDAT_RXSSEL1_INACTIVE ((uint32_t) (1 << 17)) /* SSEL1 is in inactive state */ +#define SPI_RXDAT_RXSSEL1_FLAG ((uint32_t) (1 << 17)) /* SSEL1 Rx Flag */ +/** The state of SSEL2 pin */ +#define SPI_RXDAT_RXSSEL2_ACTIVE ((uint32_t) (0 << 18)) /* SSEL2 is in active state */ +#define SPI_RXDAT_RXSSEL2_INACTIVE ((uint32_t) (1 << 18)) /* SSEL2 is in inactive state */ +#define SPI_RXDAT_RXSSEL2_FLAG ((uint32_t) (1 << 18)) /* SSEL2 Rx Flag */ +/** The state of SSEL3 pin */ +#define SPI_RXDAT_RXSSEL3_ACTIVE ((uint32_t) (0 << 19)) /* SSEL3 is in active state */ +#define SPI_RXDAT_RXSSEL3_INACTIVE ((uint32_t) (1 << 19)) /* SSEL3 is in inactive state */ +#define SPI_RXDAT_RXSSEL3_FLAG ((uint32_t) (1 << 19)) /* SSEL3 Rx Flag */ +/** Start of Transfer flag */ +#define SPI_RXDAT_SOT ((uint32_t) (1 << 20)) /* This is the first frame received after SSEL is asserted */ + +/** + * Macro defines for SPI Transmitter Data and Control register + */ +/* SPI TXDATCTL Register BitMask */ +#define SPI_TXDATCTL_BITMASK ((uint32_t) 0xF7FFFFF) +/* SPI Transmit Data */ +#define SPI_TXDATCTL_DATA(n) ((uint32_t) ((n) & 0xFFFF)) +/*Assert/Deassert SSEL0 pin*/ +#define SPI_TXDATCTL_ASSERT_SSEL0 ((uint32_t) (0 << 16)) +#define SPI_TXDATCTL_DEASSERT_SSEL0 ((uint32_t) (1 << 16)) +/*Assert/Deassert SSEL1 pin*/ +#define SPI_TXDATCTL_ASSERT_SSEL1 ((uint32_t) (0 << 17)) +#define SPI_TXDATCTL_DEASSERT_SSEL1 ((uint32_t) (1 << 17)) +/*Assert/Deassert SSEL2 pin*/ +/** Note that SSEL2, SSEL3 is only available on SPI0 not on SPI1 */ +#define SPI_TXDATCTL_ASSERT_SSEL2 ((uint32_t) (0 << 18)) +#define SPI_TXDATCTL_DEASSERT_SSEL2 ((uint32_t) (1 << 18)) +/*Assert/Deassert SSEL3 pin*/ +#define SPI_TXDATCTL_ASSERT_SSEL3 ((uint32_t) (0 << 19)) +#define SPI_TXDATCTL_DEASSERT_SSEL3 ((uint32_t) (1 << 19)) +/* Mask for Slave Select bits */ +#define SPI_TXDATCTL_SSEL_MASK ((uint32_t) (0x0F0000)) + +/** End of Transfer flag (TRANSFER_DELAY is applied after sending the current frame) */ +#define SPI_TXDATCTL_EOT ((uint32_t) (1 << 20)) /* This is the last frame of the current transfer */ +/** End of Frame flag (FRAME_DELAY is applied after sending the current part) */ +#define SPI_TXDATCTL_EOF ((uint32_t) (1 << 21)) /* This is the last part of the current frame */ +/** Receive Ignore Flag */ +#define SPI_TXDATCTL_RXIGNORE ((uint32_t) (1 << 22)) /* Received data is ignored */ +/** Transmit Data Length */ +#define SPI_TXDATCTL_LEN(n) ((uint32_t) (((n) & 0x0F) << 24)) /* Frame Length -1 */ + +/** + * Macro defines for SPI Transmitter Data Register + */ +/* SPI Transmit Data */ +#define SPI_TXDAT_DATA(n) ((uint32_t) ((n) & 0xFFFF)) + +/** + * Macro defines for SPI Transmitter Control register + */ +/* SPI TXDATCTL Register BitMask */ +#define SPI_TXCTL_BITMASK ((uint32_t) 0xF7F0000) +/*Assert/Deassert SSEL0 pin*/ +#define SPI_TXCTL_ASSERT_SSEL0 ((uint32_t) (0 << 16)) +#define SPI_TXCTL_DEASSERT_SSEL0 ((uint32_t) (1 << 16)) +/*Assert/Deassert SSEL1 pin*/ +#define SPI_TXCTL_ASSERT_SSEL1 ((uint32_t) (0 << 17)) +#define SPI_TXCTL_DEASSERT_SSEL1 ((uint32_t) (1 << 17)) +/*Assert/Deassert SSEL2 pin*/ +/** Note that SSEL2, SSEL3 is only available on SPI0 not on SPI1 */ +#define SPI_TXCTL_ASSERT_SSEL2 ((uint32_t) (0 << 18)) +#define SPI_TXCTL_DEASSERT_SSEL2 ((uint32_t) (1 << 18)) +/*Assert/Deassert SSEL3 pin*/ +#define SPI_TXCTL_ASSERT_SSEL3 ((uint32_t) (0 << 19)) +#define SPI_TXCTL_DEASSERT_SSEL3 ((uint32_t) (1 << 19)) +/** End of Transfer flag (TRANSFER_DELAY is applied after sending the current frame) */ +#define SPI_TXCTL_EOT ((uint32_t) (1 << 20)) /* This is the last frame of the current transfer */ +/** End of Frame flag (FRAME_DELAY is applied after sending the current part) */ +#define SPI_TXCTL_EOF ((uint32_t) (1 << 21)) /* This is the last part of the current frame */ +/** Receive Ignore Flag */ +#define SPI_TXCTL_RXIGNORE ((uint32_t) (1 << 22)) /* Received data is ignored */ +/** Transmit Data Length */ +#define SPI_TXCTL_LEN(n) ((uint32_t) (((n) & 0x0F) << 24)) /* Frame Length -1 */ + +/** + * Macro defines for SPI Divider register + */ +/** Rate divider value (In Master Mode only)*/ +#define SPI_DIV_VAL(n) ((uint32_t) ((n) & 0xFFFF)) /* SPI_CLK = PCLK/(DIV_VAL+1)*/ + +/** + * Macro defines for SPI Interrupt Status register + */ +/* SPI INTSTAT Register Bitmask */ +#define SPI_INTSTAT_BITMASK ((uint32_t) 0x3F) +/* Receiver Ready Flag */ +#define SPI_INTSTAT_RXRDY ((uint32_t) (1 << 0)) /* Data is ready for read */ +/* Transmitter Ready Flag */ +#define SPI_INTSTAT_TXRDY ((uint32_t) (1 << 1)) /* Data may be written to transmit buffer */ +/* Receiver Overrun interrupt flag */ +#define SPI_INTSTAT_RXOV ((uint32_t) (1 << 2)) /* Data comes while receiver buffer is in used */ +/* Transmitter Underrun interrupt flag (In Slave Mode only) */ +#define SPI_INTSTAT_TXUR ((uint32_t) (1 << 3)) /* There is no data to be sent in the next input clock */ +/* Slave Select Assert */ +#define SPI_INTSTAT_SSA ((uint32_t) (1 << 4)) /* There is SSEL transition from deasserted to asserted */ +/* Slave Select Deassert */ +#define SPI_INTSTAT_SSD ((uint32_t) (1 << 5)) /* There is SSEL transition from asserted to deasserted */ + +/** @brief SPI Mode*/ +typedef enum { + SPI_MODE_MASTER = SPI_CFG_MASTER_EN, /* Master Mode */ + SPI_MODE_SLAVE = SPI_CFG_SLAVE_EN /* Slave Mode */ +} SPI_MODE_T; + +/** @brief SPI Clock Mode*/ +typedef enum IP_SPI_CLOCK_MODE { + SPI_CLOCK_CPHA0_CPOL0 = SPI_CFG_CPOL_LO | SPI_CFG_CPHA_FIRST, /**< CPHA = 0, CPOL = 0 */ + SPI_CLOCK_CPHA0_CPOL1 = SPI_CFG_CPOL_HI | SPI_CFG_CPHA_FIRST, /**< CPHA = 0, CPOL = 1 */ + SPI_CLOCK_CPHA1_CPOL0 = SPI_CFG_CPOL_LO | SPI_CFG_CPHA_SECOND, /**< CPHA = 1, CPOL = 0 */ + SPI_CLOCK_CPHA1_CPOL1 = SPI_CFG_CPOL_HI | SPI_CFG_CPHA_SECOND, /**< CPHA = 1, CPOL = 1 */ + SPI_CLOCK_MODE0 = SPI_CLOCK_CPHA0_CPOL0,/**< alias */ + SPI_CLOCK_MODE1 = SPI_CLOCK_CPHA1_CPOL0,/**< alias */ + SPI_CLOCK_MODE2 = SPI_CLOCK_CPHA0_CPOL1,/**< alias */ + SPI_CLOCK_MODE3 = SPI_CLOCK_CPHA1_CPOL1,/**< alias */ +} SPI_CLOCK_MODE_T; + +/** @brief SPI Data Order Mode*/ +typedef enum IP_SPI_DATA_ORDER { + SPI_DATA_MSB_FIRST = SPI_CFG_MSB_FIRST_EN, /* Standard Order */ + SPI_DATA_LSB_FIRST = SPI_CFG_LSB_FIRST_EN, /* Reverse Order */ +} SPI_DATA_ORDER_T; + +/** + * @brief SPI Configure Struct + */ +typedef struct { + SPI_MODE_T Mode; /* Mode Select */ + SPI_CLOCK_MODE_T ClockMode; /* CPHA CPOL Select */ + SPI_DATA_ORDER_T DataOrder; /* MSB/LSB First */ + uint32_t SSELPol; /* SSEL Polarity Select */ + uint16_t ClkDiv; /* SPI Clock Divider Value */ +} SPI_CFG_T; + +/** + * @brief SPI Delay Configure Struct + */ +typedef struct { + uint8_t PreDelay; /* Pre-delay value in SPI clock time */ + uint8_t PostDelay; /* Post-delay value in SPI clock time */ + uint8_t FrameDelay; /* Delay value between frames of a transfer in SPI clock time */ + uint8_t TransferDelay; /* Delay value between transfers in SPI clock time */ +} SPI_DELAY_CONFIG_T; + +/** + * @brief SPI data setup structure + */ +typedef struct { + uint16_t *pTx; /**< Pointer to data buffer*/ + uint32_t TxCnt;/* Transmit Counter */ + uint16_t *pRx; /**< Pointer to data buffer*/ + uint32_t RxCnt;/* Transmit Counter */ + uint32_t Length; /**< Data Length*/ + uint32_t ssel; /**< Slave select bits */ + uint16_t DataSize; /** < The size of a frame (1-16)*/ +} SPI_DATA_SETUP_T; + +/** + * @brief Set the SPI Config register + * @param pSPI : The base SPI peripheral on the chip + * @param pConfig : SPI Configuration + * @return Nothing + */ +void Chip_SPI_SetConfig(LPC_SPI_T *pSPI, SPI_CFG_T *pConfig); + +/** + * @brief Calculate the divider for SPI clock + * @param pSPI : The base of SPI peripheral on the chip + * @param bitRate : Expected clock rate + * @return Divider value + */ +uint32_t Chip_SPI_CalClkRateDivider(LPC_SPI_T *pSPI, uint32_t bitRate); + +/** + * @brief Config SPI Delay parameters + * @param pSPI : The base of SPI peripheral on the chip + * @param pConfig : SPI Delay Configure Struct + * @return Nothing + * @note The SPI delays are setup + */ +void Chip_SPI_DelayConfig(LPC_SPI_T *pSPI, SPI_DELAY_CONFIG_T *pConfig); + +/** + * @brief SPI Initialization + * @param pSPI : The base SPI peripheral on the chip + * @return Nothing + */ +void Chip_SPI_Init(LPC_SPI_T *pSPI); + +/** + * @brief Disable SPI operation + * @param pSPI : The base of SPI peripheral on the chip + * @return Nothing + * @note The SPI controller is disabled + */ +void Chip_SPI_DeInit(LPC_SPI_T *pSPI); + +/** + * @brief Enable/Disable SPI interrupt + * @param pSPI : The base SPI peripheral on the chip + * @param IntMask : Interrupt mask + * @param NewState : ENABLE or DISABLE interrupt + * @return Nothing + */ +void Chip_SPI_Int_Cmd(LPC_SPI_T *pSPI, uint32_t IntMask, FunctionalState NewState); + +/** + * @brief Enable SPI peripheral + * @param pSPI : The base of SPI peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_SPI_Enable(LPC_SPI_T *pSPI) +{ + pSPI->CFG |= SPI_CFG_SPI_EN; +} + +/** + * @brief Disable SPI peripheral + * @param pSPI : The base of SPI peripheral on the chip + * @return Nothing + */ +STATIC INLINE void Chip_SPI_Disable(LPC_SPI_T *pSPI) +{ + pSPI->CFG &= (~SPI_CFG_SPI_EN) & SPI_CFG_BITMASK; +} + +/** + * @brief Enable loopback mode + * @param pSPI : The base of SPI peripheral on the chip + * @return Nothing + * @note Serial input is taken from the serial output (MOSI or MISO) rather + * than the serial input pin + */ +STATIC INLINE void Chip_SPI_EnableLoopBack(LPC_SPI_T *pSPI) +{ + pSPI->CFG |= SPI_CFG_LBM_EN; +} + +/** + * @brief Disable loopback mode + * @param pSPI : The base of SPI peripheral on the chip + * @return Nothing + * @note Serial input is taken from the serial input pin + */ +STATIC INLINE void Chip_SPI_DisableLoopBack(LPC_SPI_T *pSPI) +{ + pSPI->CFG &= (~SPI_CFG_LBM_EN) & SPI_CFG_BITMASK; +} + +/** + * @brief Get the current status of SPI controller + * @param pSPI : The base of SPI peripheral on the chip + * @return SPI Status (Or-ed bit value of SPI_STAT_*) + */ +STATIC INLINE uint32_t Chip_SPI_GetStatus(LPC_SPI_T *pSPI) +{ + return pSPI->STAT; +} + +/** + * @brief Clear SPI status + * @param pSPI : The base of SPI peripheral on the chip + * @param Flag : Clear Flag (Or-ed bit value of SPI_STAT_CLR_*) + * @return Nothing + */ +STATIC INLINE void Chip_SPI_ClearStatus(LPC_SPI_T *pSPI, uint32_t Flag) +{ + pSPI->STAT = (Flag & SPI_STAT_BITMASK); +} + +/** + * @brief Set control information including SSEL, EOT, EOF RXIGNORE and FLEN + * @param pSPI : The base of SPI peripheral on the chip + * @param len : Data size (1-16) + * @param Flag : Flag control (Or-ed values of SPI_TXCTL_*) + * @note The control information has no effect unless data is later written to TXDAT + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SetControlInfo(LPC_SPI_T *pSPI, uint8_t len, uint32_t Flag) +{ + pSPI->TXCTRL = (Flag & SPI_TXCTL_BITMASK) | SPI_TXDATCTL_LEN(len - 1); +} + +/** + * @brief Send the first Frame of a transfer (Rx Ignore) + * @param pSPI : The base of SPI peripheral on the chip + * @param Data : Transmit data + * @param DataSize : Data Size (1-16) + * @param ssel : ORed value of Slave Select bits + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SendFirstFrame_RxIgnore(LPC_SPI_T *pSPI, uint16_t Data, uint8_t DataSize, uint32_t ssel) +{ + pSPI->TXDATCTL = (ssel & SPI_TXDATCTL_SSEL_MASK) | SPI_TXDATCTL_EOF | SPI_TXDATCTL_RXIGNORE | SPI_TXDATCTL_LEN( + DataSize - 1) | SPI_TXDATCTL_DATA(Data); +} + +/** + * @brief Send the first Frame of a transfer + * @param pSPI : The base of SPI peripheral on the chip + * @param Data : Transmit data + * @param DataSize : Data Size (1-16) + * @param ssel : ORed value of Slave Select bits + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SendFirstFrame(LPC_SPI_T *pSPI, uint16_t Data, uint8_t DataSize, uint32_t ssel) +{ + pSPI->TXDATCTL = + (ssel & SPI_TXDATCTL_SSEL_MASK) | SPI_TXDATCTL_EOF | SPI_TXDATCTL_LEN(DataSize - 1) | SPI_TXDATCTL_DATA(Data); +} + +/** + * @brief Send the middle Frame of a transfer + * @param pSPI : The base of SPI peripheral on the chip + * @param Data : Transmit data + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SendMidFrame(LPC_SPI_T *pSPI, uint16_t Data) +{ + pSPI->TXDAT = SPI_TXDAT_DATA(Data); +} + +/** + * @brief Send the last Frame of a transfer (Rx Ignore) + * @param pSPI : The base of SPI peripheral on the chip + * @param Data : Transmit data + * @param DataSize : Data Size (1-16) + * @param ssel : ORed value of Slave Select bits + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SendLastFrame_RxIgnore(LPC_SPI_T *pSPI, uint16_t Data, uint8_t DataSize, uint32_t ssel) +{ + pSPI->TXDATCTL = (ssel & SPI_TXDATCTL_SSEL_MASK) | SPI_TXDATCTL_EOF | SPI_TXDATCTL_EOT | SPI_TXDATCTL_RXIGNORE | + SPI_TXDATCTL_LEN(DataSize - 1) | SPI_TXDATCTL_DATA(Data); +} + +/** + * @brief Send the last Frame of a transfer + * @param pSPI : The base of SPI peripheral on the chip + * @param Data : Transmit data + * @param DataSize : Data Size (1-16) + * @param ssel : ORed value of Slave Select bits + * @return Nothing + */ +STATIC INLINE void Chip_SPI_SendLastFrame(LPC_SPI_T *pSPI, uint16_t Data, uint8_t DataSize, uint32_t ssel) +{ + pSPI->TXDATCTL = (ssel & SPI_TXDATCTL_SSEL_MASK) | SPI_TXDATCTL_EOF | SPI_TXDATCTL_EOT | + SPI_TXDATCTL_LEN(DataSize - 1) | SPI_TXDATCTL_DATA(Data); +} + +/** + * @brief Read data received + * @param pSPI : The base of SPI peripheral on the chip + * @return Receive data + */ +STATIC INLINE uint16_t Chip_SPI_ReceiveFrame(LPC_SPI_T *pSPI) +{ + return SPI_RXDAT_DATA(pSPI->RXDAT); +} + +/** + * @brief Read and return Rx Slave Select and Start of transfer flags + * @param pSPI : The base of SPI peripheral on the chip + * @return Rx Slave Select and Start of transfer flags + */ +STATIC INLINE uint16_t Chip_SPI_GetReceiveInfo(LPC_SPI_T *pSPI) +{ + return pSPI->RXDAT & + (SPI_RXDAT_RXSSEL0_FLAG | SPI_RXDAT_RXSSEL0_FLAG | SPI_RXDAT_RXSSEL0_FLAG | SPI_RXDAT_RXSSEL0_FLAG | + SPI_RXDAT_SOT); +} + +/** + * @brief Get the current Interrupt status of SPI controller + * @param pSPI : The base of SPI peripheral on the chip + * @return SPI Interrupt Status (Or-ed bit value of SPI_INTSTAT_*) + */ +STATIC INLINE uint32_t Chip_SPI_GetIntStatus(LPC_SPI_T *pSPI) +{ + return pSPI->INTSTAT; +} + +/** + * @brief SPI Interrupt Read/Write + * @param pSPI : The base SPI peripheral on the chip + * @param xf_setup : Pointer to a SPI_DATA_SETUP_T structure that contains specified + * information about transmit/receive data configuration + * @return SUCCESS or ERROR + */ +Status Chip_SPI_Int_RWFrames(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *xf_setup); + +/** + * @brief SPI Polling Read/Write in blocking mode + * @param pSPI : The base SPI peripheral on the chip + * @param pXfSetup : Pointer to a SPI_DATA_SETUP_T structure that contains specified + * information about transmit/receive data configuration + * @return Actual data length has been transferred + * @note + * This function can be used in both master and slave mode. It starts with writing phase and after that, + * a reading phase is generated to read any data available in RX_FIFO. All needed information is prepared + * through xf_setup param. + */ +uint32_t Chip_SPI_RWFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup); + +/** + * @brief SPI Polling Write in blocking mode + * @param pSPI : The base SPI peripheral on the chip + * @param pXfSetup :Pointer to a SPI_DATA_SETUP_T structure that contains specified + * information about transmit/receive data configuration + * @return Actual data length has been transferred + * @note + * This function can be used in both master and slave mode. First, a writing operation will send + * the needed data. After that, a dummy reading operation is generated to clear data buffer + */ +uint32_t Chip_SPI_WriteFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup); + +/** + * @brief SPI Polling Read in blocking mode + * @param pSPI : The base SPI peripheral on the chip + * @param pXfSetup :Pointer to a SPI_DATA_SETUP_T structure that contains specified + * information about transmit/receive data configuration + * @return Actual data length has been read + * @note + * This function can be used in both master and slave mode. First, a writing operation will send + * the needed data. After that, a dummy reading operation is generated to clear data buffer + */ +uint32_t Chip_SPI_ReadFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/stopwatch.h b/lpc_chip_15xx/inc/stopwatch.h new file mode 100644 index 0000000..8e5f9cc --- /dev/null +++ b/lpc_chip_15xx/inc/stopwatch.h @@ -0,0 +1,137 @@ +/* + * @brief Common stopwatch support + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __STOPWATCH_H_ +#define __STOPWATCH_H_ + +#include "cmsis.h" + +/** @defgroup Stop_Watch CHIP: Stopwatch primitives. + * @ingroup CHIP_Common + * @{ + */ + +/** + * @brief Initialize stopwatch + * @return Nothing + */ +void StopWatch_Init(void); + +/** + * @brief Start a stopwatch + * @return Current cycle count + */ +uint32_t StopWatch_Start(void); + +/** + * @brief Returns number of ticks elapsed since stopwatch was started + * @param startTime : Time returned by StopWatch_Start(). + * @return Number of ticks elapsed since stopwatch was started + */ +STATIC INLINE uint32_t StopWatch_Elapsed(uint32_t startTime) +{ + return StopWatch_Start() - startTime; +} + +/** + * @brief Returns number of ticks per second of the stopwatch timer + * @return Number of ticks per second of the stopwatch timer + */ +uint32_t StopWatch_TicksPerSecond(void); + +/** + * @brief Converts from stopwatch ticks to mS. + * @param ticks : Duration in ticks to convert to mS. + * @return Number of mS in given number of ticks + */ +uint32_t StopWatch_TicksToMs(uint32_t ticks); + +/** + * @brief Converts from stopwatch ticks to uS. + * @param ticks : Duration in ticks to convert to uS. + * @return Number of uS in given number of ticks + */ +uint32_t StopWatch_TicksToUs(uint32_t ticks); + +/** + * @brief Converts from mS to stopwatch ticks. + * @param mS : Duration in mS to convert to ticks. + * @return Number of ticks in given number of mS + */ +uint32_t StopWatch_MsToTicks(uint32_t mS); + +/** + * @brief Converts from uS to stopwatch ticks. + * @param uS : Duration in uS to convert to ticks. + * @return Number of ticks in given number of uS + */ +uint32_t StopWatch_UsToTicks(uint32_t uS); + +/** + * @brief Delays the given number of ticks using stopwatch primitives + * @param ticks : Number of ticks to delay + * @return Nothing + */ +STATIC INLINE void StopWatch_DelayTicks(uint32_t ticks) +{ + uint32_t startTime = StopWatch_Start(); + while (StopWatch_Elapsed(startTime) < ticks) {} +} + +/** + * @brief Delays the given number of mS using stopwatch primitives + * @param mS : Number of mS to delay + * @return Nothing + */ +STATIC INLINE void StopWatch_DelayMs(uint32_t mS) +{ + uint32_t ticks = StopWatch_MsToTicks(mS); + uint32_t startTime = StopWatch_Start(); + while (StopWatch_Elapsed(startTime) < ticks) {} +} + +/** + * @brief Delays the given number of uS using stopwatch primitives + * @param uS : Number of uS to delay + * @return Nothing + */ +STATIC INLINE void StopWatch_DelayUs(uint32_t uS) +{ + uint32_t ticks = StopWatch_UsToTicks(uS); + uint32_t startTime = StopWatch_Start(); + while (StopWatch_Elapsed(startTime) < ticks) {} +} + +/** + * @} + */ + +#endif /* __STOPWATCH_H_ */ diff --git a/lpc_chip_15xx/inc/swm_15xx.h b/lpc_chip_15xx/inc/swm_15xx.h new file mode 100644 index 0000000..164d448 --- /dev/null +++ b/lpc_chip_15xx/inc/swm_15xx.h @@ -0,0 +1,274 @@ +/* + * @brief LPC15xx Switch Matrix driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SWM_15XX_H_ +#define __SWM_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SWM_15XX CHIP: LPC15xx Switch Matrix Driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15XX Switch Matrix register block structure + */ +typedef struct { + __IO uint32_t PINASSIGN[16]; /*!< Pin Assignment register array */ + __I uint32_t RESERVED0[96]; + __IO uint32_t PINENABLE[2]; /*!< fixed pin enable/disable registers */ +} LPC_SWM_T; + +/** + * @brief LPC15XX Switch Matrix Movable pins + */ +typedef enum CHIP_SWM_PIN_MOVABLE { + SWM_UART0_TXD_O = 0x00, /*!< PINASSIGN0 - UART0 TXD Output */ + SWM_UART0_RXD_I = 0x01, /*!< PINASSIGN0 - UART0 RXD Input */ + SWM_UART0_RTS_O = 0x02, /*!< PINASSIGN0 - UART0 RTS Output */ + SWM_UART0_CTS_I = 0x03, /*!< PINASSIGN0 - UART0 CTS Input */ + SWM_UART0_SCLK_IO = 0x10, /*!< PINASSIGN1 - UART0 SCLK I/O */ + SWM_UART1_TXD_O = 0x11, /*!< PINASSIGN1 - UART1 TXD Output */ + SWM_UART1_RXD_I = 0x12, /*!< PINASSIGN1 - UART1 RXD Input */ + SWM_UART1_RTS_O = 0x13, /*!< PINASSIGN1 - UART1 RTS Output */ + SWM_UART1_CTS_I = 0x20, /*!< PINASSIGN2 - UART1 CTS Input */ + SWM_UART1_SCLK_IO = 0x21, /*!< PINASSIGN2 - UART1 SCLK I/O */ + SWM_UART2_TXD_O = 0x22, /*!< PINASSIGN2 - UART2 TXD Output */ + SWM_UART2_RXD_I = 0x23, /*!< PINASSIGN2 - UART2 RXD Input */ + SWM_UART2_SCLK_IO = 0x30, /*!< PINASSIGN3 - UART2 SCLK I/O */ + SWM_SSP0_SCK_IO = 0x31, /*!< PINASSIGN3 - SSP0 SCK I/O */ + SWM_SPI0_SCK_IO = SWM_SSP0_SCK_IO, + SWM_SSP0_MOSI_IO = 0x32, /*!< PINASSIGN3 - SSP0 MOSI I/O */ + SWM_SPI0_MOSI_IO = SWM_SSP0_MOSI_IO, + SWM_SSP0_MISO_IO = 0x33, /*!< PINASSIGN3 - SSP0 MISO I/O */ + SWM_SPI0_MISO_IO = SWM_SSP0_MISO_IO, + SWM_SSP0_SSELSN_0_IO = 0x40, + SWM_SPI0_SSELSN_0_IO = SWM_SSP0_SSELSN_0_IO, + SWM_SSP0_SSELSN_1_IO = 0x41, + SWM_SPI0_SSELSN_1_IO = SWM_SSP0_SSELSN_1_IO, + SWM_SSP0_SSELSN_2_IO = 0x42, + SWM_SPI0_SSELSN_2_IO = SWM_SSP0_SSELSN_2_IO, + SWM_SSP0_SSELSN_3_IO = 0x43, + SWM_SPI0_SSELSN_3_IO = SWM_SSP0_SSELSN_3_IO, + SWM_SSP1_SCK_IO = 0x50, /*!< PINASSIGN5 - SPI1 SCK I/O */ + SWM_SPI1_SCK_IO = SWM_SSP1_SCK_IO, + SWM_SSP1_MOSI_IO = 0x51, /*!< PINASSIGN5 - SPI1 MOSI I/O */ + SWM_SPI1_MOSI_IO = SWM_SSP1_MOSI_IO, + SWM_SSP1_MISO_IO = 0x52, /*!< PINASSIGN5 - SPI1 MISO I/O */ + SWM_SPI1_MISO_IO = SWM_SSP1_MISO_IO, + SWM_SSP1_SSELSN_0_IO = 0x53, /*!< PINASSIGN5 - SPI1 SSEL I/O */ + SWM_SPI1_SSELSN_0_IO = SWM_SSP1_SSELSN_0_IO, + SWM_SSP1_SSELSN_1_IO = 0x60, + SWM_SPI1_SSELSN_1_IO = SWM_SSP1_SSELSN_1_IO, + SWM_CAN_TD1_O = 0x61, + SWM_CAN_RD1_I = 0x62, + SWM_USB_VBUS_I = 0x70, + SWM_SCT0_OUT0_O = 0x71, + SWM_SCT0_OUT1_O = 0x72, + SWM_SCT0_OUT2_O = 0x73, + SWM_SCT1_OUT0_O = 0x80, + SWM_SCT1_OUT1_O = 0x81, + SWM_SCT1_OUT2_O = 0x82, + SWM_SCT2_OUT0_O = 0x83, + SWM_SCT2_OUT1_O = 0x90, + SWM_SCT2_OUT2_O = 0x91, + SWM_SCT3_OUT0_O = 0x92, + SWM_SCT3_OUT1_O = 0x93, + SWM_SCT3_OUT2_O = 0xA0, + SWM_SCT_ABORT0_I = 0xA1, + SWM_SCT_ABORT1_I = 0xA2, + SWM_ADC0_PIN_TRIG0_I = 0xA3, + SWM_ADC0_PIN_TRIG1_I = 0xB0, + SWM_ADC1_PIN_TRIG0_I = 0xB1, + SWM_ADC1_PIN_TRIG1_I = 0xB2, + SWM_DAC_PIN_TRIG_I = 0xB3, + SWM_DAC_SHUTOFF_I = 0xC0, + SWM_ACMP0_OUT_O = 0xC1, + SWM_ACMP1_OUT_O = 0xC2, + SWM_ACMP2_OUT_O = 0xC3, + SWM_ACMP3_OUT_O = 0xD0, + SWM_CLK_OUT_O = 0xD1, + SWM_ROSC0_O = 0xD2, + SWM_ROSC_RST0_I = 0xD3, + SWM_USB_FRAME_TOG_O = 0xE0, + SWM_QEI0_PHA_I = 0xE1, + SWM_QEI0_PHB_I = 0xE2, + SWM_QEI0_IDX_I = 0xE3, + SWM_GPIO_INT_BMATCH_O = 0xF0, + SWM_SWO_O = 0xF1, +} CHIP_SWM_PIN_MOVABLE_T; + +/** + * @brief LPC15XX Switch Matrix Fixed pins + */ +typedef enum CHIP_SWM_PIN_FIXED { + SWM_FIXED_ADC0_0 = 0x00, /*!< ADC0_0 fixed pin enable/disable on pin P0_8 */ + SWM_FIXED_ADC0_1 = 0x01, /*!< ADC0_1 fixed pin enable/disable on pin P0_7 */ + SWM_FIXED_ADC0_2 = 0x02, /*!< ADC0_2 fixed pin enable/disable on pin P0_6 */ + SWM_FIXED_ADC0_3 = 0x03, /*!< ADC0_3 fixed pin enable/disable on pin P0_5 */ + SWM_FIXED_ADC0_4 = 0x04, /*!< ADC0_4 fixed pin enable/disable on pin P0_4 */ + SWM_FIXED_ADC0_5 = 0x05, /*!< ADC0_5 fixed pin enable/disable on pin P0_3 */ + SWM_FIXED_ADC0_6 = 0x06, /*!< ADC0_6 fixed pin enable/disable on pin P0_2 */ + SWM_FIXED_ADC0_7 = 0x07, /*!< ADC0_7 fixed pin enable/disable on pin P0_1 */ + SWM_FIXED_ADC0_8 = 0x08, /*!< ADC0_8 fixed pin enable/disable on pin P1_0 */ + SWM_FIXED_ADC0_9 = 0x09, /*!< ADC0_9 fixed pin enable/disable on pin P0_31 */ + SWM_FIXED_ADC0_10 = 0x0A, /*!< ADC0_10 fixed pin enable/disable on pin P0_0 */ + SWM_FIXED_ADC0_11 = 0x0B, /*!< ADC0_11 fixed pin enable/disable on pin P0_30 */ + SWM_FIXED_ADC1_0 = 0x0C, /*!< ADC1_0 fixed pin enable/disable/disable on pin P1_1 */ + SWM_FIXED_ADC1_1 = 0x0D, /*!< ADC1_1 fixed pin enable/disable on pin P0_9 */ + SWM_FIXED_ADC1_2 = 0x0E, /*!< ADC1_2 fixed pin enable/disable on pin P0_10 */ + SWM_FIXED_ADC1_3 = 0x0F, /*!< ADC1_3 fixed pin enable/disable on pin P0_11 */ + SWM_FIXED_ADC1_4 = 0x10, /*!< ADC1_4 fixed pin enable/disable on pin P1_2 */ + SWM_FIXED_ADC1_5 = 0x11, /*!< ADC1_5 fixed pin enable/disable on pin P1_3 */ + SWM_FIXED_ADC1_6 = 0x12, /*!< ADC1_6 fixed pin enable/disable on pin P0_13 */ + SWM_FIXED_ADC1_7 = 0x13, /*!< ADC1_7 fixed pin enable/disable on pin P0_14 */ + SWM_FIXED_ADC1_8 = 0x14, /*!< ADC1_8 fixed pin enable/disable on pin P0_15 */ + SWM_FIXED_ADC1_9 = 0x15, /*!< ADC1_9 fixed pin enable/disable on pin P0_16 */ + SWM_FIXED_ADC1_10 = 0x16, /*!< ADC1_10 fixed pin enable/disable on pin P1_4 */ + SWM_FIXED_ADC1_11 = 0x17, /*!< ADC1_11 fixed pin enable/disable on pin P1_5 */ + SWM_FIXED_DAC_OUT = 0x18, /*!< DAC_OUT fixed pin enable/disable on pin P0_12 */ + SWM_FIXED_ACMP_I1 = 0x19, /*!< ACMP input 1 (common input) fixed pin enable/disable on pin P0_27 */ + SWM_FIXED_ACMP_I2 = 0x1A, /*!< ACMP input 1 (common input) fixed pin enable/disable on pin P1_6 */ + SWM_FIXED_ACMP0_I3 = 0x1B, /*!< ACMP comparator 0 input 3 fixed pin enable/disable on pin P0_26 */ + SWM_FIXED_ACMP0_I4 = 0x1C, /*!< ACMP comparator 0 input 4 fixed pin enable/disable on pin P0_25 */ + SWM_FIXED_ACMP1_I3 = 0x1D, /*!< ACMP comparator 1 input 3 fixed pin enable/disable on pin P0_28 */ + SWM_FIXED_ACMP1_I4 = 0x1E, /*!< ACMP comparator 1 input 4 fixed pin enable/disable on pin P1_10 */ + SWM_FIXED_ACMP2_I3 = 0x1F, /*!< ACMP comparator 2 input 3 fixed pin enable/disable on pin P0_29 */ + SWM_FIXED_ACMP2_I4 = 0x80, /*!< ACMP comparator 2 input 4 fixed pin enable/disable on pin P1_9 */ + SWM_FIXED_ACMP3_I3 = 0x81, /*!< ACMP comparator 3 input 3 fixed pin enable/disable on pin P1_8 */ + SWM_FIXED_ACMP3_I4 = 0x82, /*!< ACMP comparator 3 input 4 fixed pin enable/disable on pin P1_7 */ + SWM_FIXED_I2C0_SDA = 0x83, /*!< I2C0_SDA fixed pin enable/disable on pin P0_23 */ + SWM_FIXED_I2C0_SCL = 0x84, /*!< I2C0_SCL fixed pin enable/disable on pin P0_22 */ + SWM_FIXED_SCT0_OUT3 = 0x85, /*!< SCT0_OUT3 fixed pin enable/disable on pin P0_0 */ + SWM_FIXED_SCT0_OUT4 = 0x86, /*!< SCT0_OUT4 fixed pin enable/disable on pin P0_1 */ + SWM_FIXED_SCT0_OUT5 = 0x87, /*!< SCT0_OUT5 fixed pin enable/disable on pin P0_18 */ + SWM_FIXED_SCT0_OUT6 = 0x88, /*!< SCT0_OUT6 fixed pin enable/disable on pin P0_24 */ + SWM_FIXED_SCT0_OUT7 = 0x89, /*!< SCT0_OUT7 fixed pin enable/disable on pin P1_14 */ + SWM_FIXED_SCT1_OUT3 = 0x8A, /*!< SCT1_OUT3 fixed pin enable/disable on pin P0_2 */ + SWM_FIXED_SCT1_OUT4 = 0x8B, /*!< SCT1_OUT4 fixed pin enable/disable on pin P0_3 */ + SWM_FIXED_SCT1_OUT5 = 0x8C, /*!< SCT1_OUT5 fixed pin enable/disable on pin P0_14 */ + SWM_FIXED_SCT1_OUT6 = 0x8D, /*!< SCT1_OUT6 fixed pin enable/disable on pin P0_20 */ + SWM_FIXED_SCT1_OUT7 = 0x8E, /*!< SCT1_OUT7 fixed pin enable/disable on pin P1_17 */ + SWM_FIXED_SCT2_OUT3 = 0x8F, /*!< SCT2_OUT3 fixed pin enable/disable on pin P0_6 */ + SWM_FIXED_SCT2_OUT4 = 0x90, /*!< SCT2_OUT4 fixed pin enable/disable on pin P0_29 */ + SWM_FIXED_SCT2_OUT5 = 0x91, /*!< SCT2_OUT5 fixed pin enable/disable on pin P1_20 */ + SWM_FIXED_SCT3_OUT3 = 0x92, /*!< SCT3_OUT3 fixed pin enable/disable on pin P0_26 */ + SWM_FIXED_SCT3_OUT4 = 0x93, /*!< SCT3_OUT4 fixed pin enable/disable on pin P1_8 */ + SWM_FIXED_SCT3_OUT5 = 0x94, /*!< SCT3_OUT5 fixed pin enable/disable on pin P1_24 */ + SWM_FIXED_RESETN = 0x95, /*!< RESETN fixed pin enable/disable on pin P0_21 */ + SWM_FIXED_SWCLK_TCK = 0x96, /*!< SWCLK_TCK fixed pin enable/disable on pin P0_19 */ + SWM_FIXED_SWDIO = 0x97, /*!< SWDIO fixed pin enable/disable on pin P0_20 */ +} CHIP_SWM_PIN_FIXED_T; + +/** + * @brief Initialize the SWM module + * @return Nothing + * @note This function only enables the SWM clock. + */ +STATIC INLINE void Chip_SWM_Init(void) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM); +} + +/** + * @brief Deinitialise the SWM module + * @return Nothing + * @note This function only disables the SWM clock. + */ +STATIC INLINE void Chip_SWM_Deinit(void) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM); +} + +/** + * @brief Assign movable pin function to physical pin in Switch Matrix + * @param movable : Movable pin function + * @param assign : Physical pin to be assigned + * @return Nothing + */ +void Chip_SWM_MovablePinAssign(CHIP_SWM_PIN_MOVABLE_T movable, uint8_t assign); + +/** + * @brief Assign movable pin function to port and pin in the Switch Matrix + * @param movable : Movable pin function + * @param port : Port number + * @param pin : Pin number + * @return Nothing + * @note This function does the same thing as Chip_SWM_MovablePinAssign() + * except works with a port and pin number instead of a physical + * pin number. + */ +STATIC INLINE void Chip_SWM_MovablePortPinAssign(CHIP_SWM_PIN_MOVABLE_T movable, uint8_t port, uint8_t pin) +{ + Chip_SWM_MovablePinAssign(movable, ((port * 32) + pin)); +} + +/** + * @brief Enables a fixed function pin in the Switch Matrix + * @param pin : Pin to be enabled + * @return Nothing + */ +void Chip_SWM_EnableFixedPin(CHIP_SWM_PIN_FIXED_T pin); + +/** + * @brief Disables a fixed function pin in the Switch Matrix + * @param pin : Pin to be disabled + * @return Nothing + */ +void Chip_SWM_DisableFixedPin(CHIP_SWM_PIN_FIXED_T pin); + +/** + * @brief Enables or disables a fixed function pin in the Switch Matrix + * @param pin : Pin to be enabled or disabled + * @param enable : True to enable the pin, False to disable the pin + * @return Nothing + */ +void Chip_SWM_FixedPinEnable(CHIP_SWM_PIN_FIXED_T pin, bool enable); + +/** + * @brief Tests whether a fixed function pin is enabled or disabled in the Switch Matrix + * @param pin : The pin to test whether it is enabled or disabled + * @return True if the pin is enabled, False if disabled + */ +bool Chip_SWM_IsFixedPinEnabled(CHIP_SWM_PIN_FIXED_T pin); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SWM_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/sys_config.h b/lpc_chip_15xx/inc/sys_config.h new file mode 100644 index 0000000..a36207d --- /dev/null +++ b/lpc_chip_15xx/inc/sys_config.h @@ -0,0 +1,36 @@ +/* + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SYS_CONFIG_H_ +#define __SYS_CONFIG_H_ + +/* LPC15xx chip familiy is suppored */ +#define CHIP_LPC15XX + +#endif /* __SYS_CONFIG_H_ */ diff --git a/lpc_chip_15xx/inc/sysctl_15xx.h b/lpc_chip_15xx/inc/sysctl_15xx.h new file mode 100644 index 0000000..a31d9c5 --- /dev/null +++ b/lpc_chip_15xx/inc/sysctl_15xx.h @@ -0,0 +1,619 @@ +/* + * @brief LPC15XX System Control registers and control functions + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __SYSCTL_15XX_H_ +#define __SYSCTL_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SYSCTL_15XX CHIP: LPC15xx System Control block driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief LPC15XX System Control block structure + */ +typedef struct { /*!< SYSCTL Structure */ + __IO uint32_t SYSMEMREMAP; /*!< System Memory remap register */ + __I uint32_t RESERVED0[2]; + __IO uint32_t AHBBUFEN0; + __IO uint32_t AHBBUFEN1; + __IO uint32_t SYSTCKCAL; /*!< System tick counter calibration register */ + __I uint32_t RESERVED1[1]; + __IO uint32_t NMISRC; /*!< NMI source control register */ + __I uint32_t RESERVED2[8]; + __IO uint32_t SYSRSTSTAT; /*!< System Reset Status register */ + __IO uint32_t PRESETCTRL[2]; /*!< Peripheral reset Control registers */ + __I uint32_t PIOPORCAP[3]; /*!< POR captured PIO status registers */ + __I uint32_t RESERVED3[10]; + __IO uint32_t MAINCLKSELA; /*!< Main clock source A select register */ + __IO uint32_t MAINCLKSELB; /*!< Main clock source B select register */ + __IO uint32_t USBCLKSEL; /*!< USB clock source select register */ + __IO uint32_t ADCASYNCCLKSEL; /*!< ADC asynchronous clock source select register */ + __I uint32_t RESERVED4[1]; + __IO uint32_t CLKOUTSEL[2]; /*!< Clock out source select registers */ + __I uint32_t RESERVED5[1]; + __IO uint32_t SYSPLLCLKSEL; /*!< System PLL clock source select register */ + __IO uint32_t USBPLLCLKSEL; /*!< USB PLL clock source select register */ + __IO uint32_t SCTPLLCLKSEL; /*!< SCT PLL clock source select register */ + __I uint32_t RESERVED6[5]; + __IO uint32_t SYSAHBCLKDIV; /*!< System Clock divider register */ + __IO uint32_t SYSAHBCLKCTRL[2];/*!< System clock control registers */ + __IO uint32_t SYSTICKCLKDIV; /*!< SYSTICK clock divider */ + __IO uint32_t UARTCLKDIV; /*!< UART clock divider register */ + __IO uint32_t IOCONCLKDIV; /*!< programmable glitch filter divider registers for IOCON */ + __IO uint32_t TRACECLKDIV; /*!< ARM trace clock divider register */ + __I uint32_t RESERVED7[4]; + __IO uint32_t USBCLKDIV; /*!< USB clock source divider register */ + __IO uint32_t ADCASYNCCLKDIV; /*!< Asynchronous ADC clock divider */ + __I uint32_t RESERVED8[1]; + __IO uint32_t CLKOUTDIV; /*!< Clock out divider register */ + __I uint32_t RESERVED9[9]; + __IO uint32_t FREQMECTRL; /*!< Frequency measure register */ + __IO uint32_t FLASHCFG; /*!< Flash configuration register */ + __IO uint32_t FRGCTRL; /*!< USART fractional baud rate generator control register */ + __IO uint32_t USBCLKCTRL; /*!< USB clock control register */ + __I uint32_t USBCLKST; /*!< USB clock status register */ + __I uint32_t RESERVED10[19]; + __IO uint32_t BODCTRL; /*!< Brown Out Detect register */ + __I uint32_t IRCCTRL; + __IO uint32_t SYSOSCCTRL; /*!< System Oscillator control register */ + __I uint32_t RESERVED11[1]; + __IO uint32_t RTCOSCCTRL; /*!< RTC Oscillator control register */ + __I uint32_t RESERVED12[1]; + __IO uint32_t SYSPLLCTRL; /*!< System PLL control register */ + __I uint32_t SYSPLLSTAT; /*!< System PLL status register */ + __IO uint32_t USBPLLCTRL; /*!< USB PLL control register */ + __I uint32_t USBPLLSTAT; /*!< USB PLL status register */ + __IO uint32_t SCTPLLCTRL; /*!< SCT PLL control register */ + __I uint32_t SCTPLLSTAT; /*!< SCT PLL status register */ + __I uint32_t RESERVED13[21]; + __IO uint32_t PDWAKECFG; /*!< Power down states in wake up from deep sleep register */ + __IO uint32_t PDRUNCFG; /*!< Power configuration register*/ + __I uint32_t RESERVED14[3]; + __IO uint32_t STARTERP[2]; /*!< Start logic interrupt wake-up enable registers */ + __I uint32_t RESERVED15[117]; + __I uint32_t JTAG_IDCODE; /*!< JTAG ID code register */ + __I uint32_t DEVICEID[2]; /*!< Device ID registers */ +} LPC_SYSCTL_T; + +/** + * System memory remap modes used to remap interrupt vectors + */ +typedef enum CHIP_SYSCTL_BOOT_MODE_REMAP { + REMAP_BOOT_LOADER_MODE = 0, /*!< Interrupt vectors are re-mapped to Boot ROM */ + REMAP_USER_RAM_MODE, /*!< Interrupt vectors are re-mapped to Static RAM */ + REMAP_USER_FLASH_MODE /*!< Interrupt vectors are not re-mapped and reside in Flash */ +} CHIP_SYSCTL_BOOT_MODE_REMAP_T; + +/** + * @brief Re-map interrupt vectors + * @param remap : system memory map value + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_Map(CHIP_SYSCTL_BOOT_MODE_REMAP_T remap) +{ + LPC_SYSCTL->SYSMEMREMAP = (uint32_t) remap; +} + +/** + * Peripheral reset identifiers, not available on all devices + */ +typedef enum { + /* PRESETCTRL0 resets */ + RESET_FLASH = 7, /*!< FLASH controller reset control */ + RESET_EEPROM = 9, /*!< EEPROM controller reset control */ + RESET_MUX = 11, /*!< Input mux reset control */ + RESET_IOCON = 13, /*!< IOCON reset control */ + RESET_PININT = 18, /*!< Pin interrupt (PINT) reset reset control */ + RESET_GINT, /*!< Grouped interrupt (GINT) reset control */ + RESET_DMA, /*!< DMA reset control */ + RESET_CRC, /*!< CRC reset control */ + RESET_ADC0 = 27, /*!< ADC0 reset control */ + RESET_ADC1, /*!< ADC1 reset control */ + RESET_ACMP = 30, /*!< Analog Comparator (all 4 ACMP) reset control */ + RESET_MRT = 32 + 0, /*!< Multi-rate timer (MRT) reset control */ + RESET_RIT, /*!< Repetitive interrupt timer (RIT) reset control */ + RESET_SCT0, /*!< State configurable timer 0 (SCT0) reset control */ + RESET_SCT1, /*!< State configurable timer 1 (SCT1) reset control */ + RESET_SCT2, /*!< State configurable timer 2 (SCT2) reset control */ + RESET_SCT3, /*!< State configurable timer 3 (SCT3) reset control */ + RESET_SCTIPU, /*!< State configurable timer IPU (SCTIPU) reset control */ + RESET_CAN, /*!< CAN reset control */ + RESET_SPI0 = 32 + 9, /*!< SPI0 reset control */ + RESET_SPI1, /*!< SPI1 reset control */ + RESET_I2C0 = 32 + 13, /*!< I2C0 reset control */ + RESET_UART0 = 32 + 17, /*!< UART0 reset control */ + RESET_UART1, /*!< UART1 reset control */ + RESET_UART2, /*!< UART2 reset control */ + RESET_QEI0 = 32 + 21, /*!< QEI0 reset control */ + RESET_USB = 32 + 23 /*!< USB reset control */ +} CHIP_SYSCTL_PERIPH_RESET_T; + +/** + * @brief Assert reset for a peripheral + * @param periph : Peripheral to assert reset for + * @return Nothing + * @note The peripheral will stay in reset until reset is de-asserted. Call + * Chip_SYSCTL_DeassertPeriphReset() to de-assert the reset. + */ +void Chip_SYSCTL_AssertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph); + +/** + * @brief De-assert reset for a peripheral + * @param periph : Peripheral to de-assert reset for + * @return Nothing + */ +void Chip_SYSCTL_DeassertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph); + +/** + * @brief Resets a peripheral + * @param periph : Peripheral to reset + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_PeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph) +{ + Chip_SYSCTL_AssertPeriphReset(periph); + Chip_SYSCTL_DeassertPeriphReset(periph); +} + +/** + * System reset status + */ +#define SYSCTL_RST_POR (1 << 0) /*!< POR reset status */ +#define SYSCTL_RST_EXTRST (1 << 1) /*!< External reset status */ +#define SYSCTL_RST_WDT (1 << 2) /*!< Watchdog reset status */ +#define SYSCTL_RST_BOD (1 << 3) /*!< Brown-out detect reset status */ +#define SYSCTL_RST_SYSRST (1 << 4) /*!< software system reset status */ + +/** + * @brief Get system reset status + * @return An Or'ed value of SYSCTL_RST_* + * @note This function returns the detected reset source(s). Mask with an + * SYSCTL_RST_* value to determine if a reset has occurred. + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetSystemRSTStatus(void) +{ + return LPC_SYSCTL->SYSRSTSTAT; +} + +/** + * @brief Clear system reset status + * @param reset : An Or'ed value of SYSCTL_RST_* statuses to clear + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_ClearSystemRSTStatus(uint32_t reset) +{ + LPC_SYSCTL->SYSRSTSTAT = reset; +} + +/** + * @brief Read POR captured PIO status at reset + * @param index : POR register index 0, 1, or 2 + * @return captured POR PIO status for ports 0, 1, or 2 + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetPORPIOStatus(int index) +{ + return LPC_SYSCTL->PIOPORCAP[index]; +} + +/** + * Brown-out detector reset level + */ +typedef enum CHIP_SYSCTL_BODRSTLVL { + SYSCTL_BODRSTLVL_RESERVED0, + SYSCTL_BODRSTLVL_RESERVED1, + SYSCTL_BODRSTLVL_2_34V, /*!< Brown-out reset at 2.34v */ + SYSCTL_BODRSTLVL_2_64V, /*!< Brown-out reset at 2.64v */ +} CHIP_SYSCTL_BODRSTLVL_T; + +/** + * Brown-out detector interrupt level + */ +typedef enum CHIP_SYSCTL_BODRINTVAL { + SYSCTL_BODINTVAL_RESERVED0, + SYSCTL_BODINTVAL_RESERVED1, + SYSCTL_BODINTVAL_2_55V, /*!< Brown-out interrupt at 2.55v */ + SYSCTL_BODINTVAL_2_83V, /*!< Brown-out interrupt at 2.83v */ +} CHIP_SYSCTL_BODRINTVAL_T; + +/** + * @brief Set brown-out detection interrupt and reset levels + * @param rstlvl : Brown-out detector reset level + * @param intlvl : Brown-out interrupt level + * @return Nothing + * @note Brown-out detection reset will be disabled upon exiting this function. + * Use Chip_SYSCTL_EnableBODReset() to re-enable. + */ +STATIC INLINE void Chip_SYSCTL_SetBODLevels(CHIP_SYSCTL_BODRSTLVL_T rstlvl, + CHIP_SYSCTL_BODRINTVAL_T intlvl) +{ + LPC_SYSCTL->BODCTRL = ((uint32_t) rstlvl) | (((uint32_t) intlvl) << 2); +} + +/** + * @brief Enable brown-out detection reset + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_EnableBODReset(void) +{ + LPC_SYSCTL->BODCTRL |= (1 << 4); +} + +/** + * @brief Disable brown-out detection reset + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_DisableBODReset(void) +{ + LPC_SYSCTL->BODCTRL &= ~(1 << 4); +} + +/** + * @brief Set System tick timer calibration value + * @param sysCalVal : System tick timer calibration value + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_SetSYSTCKCAL(uint32_t sysCalVal) +{ + LPC_SYSCTL->SYSTCKCAL = sysCalVal; +} + +/** + * Non-Maskable Interrupt Enable/Disable value + */ +#define SYSCTL_NMISRC_ENABLE (1UL << 31) /*!< Enable the Non-Maskable Interrupt (NMI) source */ + +/** + * @brief Set source for non-maskable interrupt (NMI) + * @param intsrc : IRQ number to assign to the NMI + * @return Nothing + * @note The NMI source will be disabled upon exiting this function. Use the + * Chip_SYSCTL_EnableNMISource() function to enable the NMI source. + */ +STATIC INLINE void Chip_SYSCTL_SetNMISource(uint32_t intsrc) +{ + LPC_SYSCTL->NMISRC = 0; /* Disable first */ + LPC_SYSCTL->NMISRC = intsrc; +} + +/** + * @brief Enable interrupt used for NMI source + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_EnableNMISource(void) +{ + LPC_SYSCTL->NMISRC |= SYSCTL_NMISRC_ENABLE; +} + +/** + * @brief Disable interrupt used for NMI source + * @return Nothing + */ +STATIC INLINE void Chip_SYSCTL_DisableNMISource(void) +{ + LPC_SYSCTL->NMISRC &= ~(SYSCTL_NMISRC_ENABLE); +} + +/** + * @brief Starts a frequency measurement cycle + * @return Nothing + * @note This function is meant to be used with the Chip_INMUX_SetFreqMeasRefClock() + * and Chip_INMUX_SetFreqMeasTargClock() functions. + */ +STATIC INLINE void Chip_SYSCTL_StartFreqMeas(void) +{ + LPC_SYSCTL->FREQMECTRL = 0; + LPC_SYSCTL->FREQMECTRL = (1UL << 31); +} + +/** + * @brief Indicates when a frequency measurement cycle is complete + * @return true if a measurement cycle is active, otherwise false + */ +STATIC INLINE bool Chip_SYSCTL_IsFreqMeasComplete(void) +{ + return (bool) ((LPC_SYSCTL->FREQMECTRL & (1UL << 31)) == 0); +} + +/** + * @brief Returns the raw capture value for a frequency measurement cycle + * @return raw cpature value (this is not a frequency) + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetRawFreqMeasCapval(void) +{ + return LPC_SYSCTL->FREQMECTRL & 0x3FFF; +} + +/** + * @brief Returns the computed value for a frequency measurement cycle + * @param refClockRate : Reference clock rate used during the frequency measurement cycle + * @return Computed cpature value + */ +uint32_t Chip_SYSCTL_GetCompFreqMeas(uint32_t refClockRate); + +/** + * @brief FLASH Access time definitions + */ +typedef enum { + SYSCTL_FLASHTIM_25MHZ_CPU = 0, /*!< Flash accesses use 1 CPU clocks. Use for up to 25 MHz CPU clock*/ + SYSCTL_FLASHTIM_55MHZ_CPU = 1, /*!< Flash accesses use 2 CPU clocks. Use for up to 55 MHz CPU clock*/ + SYSCTL_FLASHTIM_72MHZ_CPU = 2, /*!< Flash accesses use 3 CPU clocks. Use for up to 72 MHz CPU clock*/ +} SYSCTL_FLASHTIM_T; + +/** + * @brief Set FLASH access time in clocks + * @param clks : Clock cycles for FLASH access (minus 1) + * @return Nothing + */ +STATIC INLINE void Chip_FMC_SetFLASHAccess(SYSCTL_FLASHTIM_T clks) +{ + uint32_t tmp = LPC_SYSCTL->FLASHCFG & (~(0x3 << 12)); + + /* Don't alter other bits */ + LPC_SYSCTL->FLASHCFG = tmp | ((clks & 0x03) << 12); +} + +/** + * @brief Setup USB clock control + * @param ap_clk : USB need_clock signal control (0 or 1) + * @param pol_clk : USB need_clock polarity for triggering the USB wake-up interrupt (0 or 1) + * @return Nothing + * @note See the USBCLKCTRL register in the user manual for these settings. + */ +STATIC INLINE void Chip_SYSCTL_SetUSBCLKCTRL(uint32_t ap_clk, uint32_t pol_clk) +{ + LPC_SYSCTL->USBCLKCTRL = ap_clk | (pol_clk << 1); +} + +/** + * @brief Returns the status of the USB need_clock signal + * @return true if USB need_clock status is high, otherwise false + */ +STATIC INLINE bool Chip_SYSCTL_GetUSBCLKStatus(void) +{ + return (bool) ((LPC_SYSCTL->USBCLKST & 0x1) != 0); +} + +/** + * Peripheral interrupt wakeup events on STARTERP0 only + */ +#define SYSCTL_ERP0_WAKEUP_WDTINT (1 << 0) /*!< WWDT interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_BODINT (1 << 1) /*!< Brown out detector interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_GINT0INT (1 << 5) /*!< Group interrupt 0 wake-up */ +#define SYSCTL_ERP0_WAKEUP_GINT1INT (1 << 6) /*!< Group interrupt 1 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT0INT (1 << 7) /*!< GPIO pin interrupt 0 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT1INT (1 << 8) /*!< GPIO pin interrupt 1 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT2INT (1 << 9) /*!< GPIO pin interrupt 2 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT3INT (1 << 10) /*!< GPIO pin interrupt 3 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT4INT (1 << 11) /*!< GPIO pin interrupt 4 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT5INT (1 << 12) /*!< GPIO pin interrupt 5 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT6INT (1 << 13) /*!< GPIO pin interrupt 6 wake-up */ +#define SYSCTL_ERP0_WAKEUP_PINT7INT (1 << 14) /*!< GPIO pin interrupt 7 wake-up */ +#define SYSCTL_ERP0_WAKEUP_USART0INT (1 << 21) /*!< USART0 interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_USART1INT (1 << 22) /*!< USART1 interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_USART2INT (1 << 23) /*!< USART2 interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_I2CINT (1 << 24) /*!< I2C interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_SPI0INT (1 << 25) /*!< SPI0 interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_SPI1INT (1 << 26) /*!< SPI1 interrupt wake-up */ +#define SYSCTL_ERP0_WAKEUP_USB_WAKEUP (1 << 30) /*!< USB need_clock signal wake-up */ + +/** + * @brief Enables a peripheral's wakeup logic (STARTERP0 only) + * @param periphmask : OR'ed values of SYSCTL_ERP0_* for wakeup + * @return Nothing + * @note Use this function only with definitions of type SYSCTL_ERP0_*. Do + * not use or mix with SYSCTL_ERP1_* definitions. + */ +STATIC INLINE void Chip_SYSCTL_EnableERP0PeriphWakeup(uint32_t periphmask) +{ + LPC_SYSCTL->STARTERP[0] |= periphmask; +} + +/** + * @brief Disables a peripheral's wakeup logic (STARTERP0 only) + * @param periphmask : OR'ed values of SYSCTL_ERP0_* for wakeup + * @return Nothing + * @note Use this function only with definitions of type SYSCTL_ERP0_*. Do + * not use or mix with SYSCTL_ERP1_* definitions. + */ +STATIC INLINE void Chip_SYSCTL_DisableERP0PeriphWakeup(uint32_t periphmask) +{ + LPC_SYSCTL->STARTERP[0] &= ~periphmask; +} + +/** + * Peripheral interrupt wakeup events on STARTERP1 only + */ +#define SYSCTL_ERP1_WAKEUP_ACMP0INT (1 << 8) /*!< Analog comparator 0 interrupt wake-up */ +#define SYSCTL_ERP1_WAKEUP_ACMP1INT (1 << 9) /*!< Analog comparator 1 interrupt wake-up */ +#define SYSCTL_ERP1_WAKEUP_ACMP2INT (1 << 10) /*!< Analog comparator 2 interrupt wake-up */ +#define SYSCTL_ERP1_WAKEUP_ACMP3INT (1 << 11) /*!< Analog comparator 3 interrupt wake-up */ +#define SYSCTL_ERP1_WAKEUP_RTCALARMINT (1 << 13) /*!< RTC alarm interrupt wake-up */ +#define SYSCTL_ERP1_WAKEUP_RTCWAKEINT (1 << 14) /*!< RTC wake (1KHz wake) interrupt wake-up */ + +/** + * @brief Enables a peripheral's wakeup logic (STARTERP0 only) + * @param periphmask : OR'ed values of SYSCTL_ERP1_* for wakeup + * @return Nothing + * @note Use this function only with definitions of type SYSCTL_ERP1_*. Do + * not use or mix with SYSCTL_ERP1_* definitions. + */ +STATIC INLINE void Chip_SYSCTL_EnableERP1PeriphWakeup(uint32_t periphmask) +{ + LPC_SYSCTL->STARTERP[1] |= periphmask; +} + +/** + * @brief Disables a peripheral's wakeup logic (STARTERP1 only) + * @param periphmask : OR'ed values of SYSCTL_ERP1_* for wakeup + * @return Nothing + * @note Use this function only with definitions of type SYSCTL_ERP1_*. Do + * not use or mix with SYSCTL_ERP1_* definitions. + */ +STATIC INLINE void Chip_SYSCTL_DisableERP1PeriphWakeup(uint32_t periphmask) +{ + LPC_SYSCTL->STARTERP[1] &= ~periphmask; +} + +/** + * Deep sleep to wakeup setup values + */ +#define SYSCTL_SLPWAKE_TBD0_PD (1 << 0) /*!< TBD0 wake-up configuration */ +#define SYSCTL_SLPWAKE_TBD1_PD (1 << 1) /*!< TBD1 wake-up configuration */ +#define SYSCTL_SLPWAKE_TBD2_PD (1 << 2) /*!< TBD2 wake-up configuration */ +#define SYSCTL_SLPWAKE_IRCOUT_PD (1 << 3) /*!< IRC oscillator output wake-up configuration */ +#define SYSCTL_SLPWAKE_IRC_PD (1 << 4) /*!< IRC oscillator power-down wake-up configuration */ +#define SYSCTL_SLPWAKE_FLASH_PD (1 << 5) /*!< Flash wake-up configuration */ +#define SYSCTL_SLPWAKE_EEPROM_PD (1 << 6) /*!< EEPROM wake-up configuration */ +#define SYSCTL_SLPWAKE_BOD_PD (1 << 8) /*!< BOD wake-up configuration */ +#define SYSCTL_SLPWAKE_USBPHY_PD (1 << 9) /*!< USB PHY wake-up configuration */ +#define SYSCTL_SLPWAKE_ADC0_PD (1 << 10) /*!< ADC0 wake-up configuration */ +#define SYSCTL_SLPWAKE_ADC1_PD (1 << 11) /*!< ADC1 wake-up configuration */ +#define SYSCTL_SLPWAKE_DAC_PD (1 << 12) /*!< DAC wake-up configuration */ +#define SYSCTL_SLPWAKE_ACMP0_PD (1 << 13) /*!< ACMP0 wake-up configuration */ +#define SYSCTL_SLPWAKE_ACMP1_PD (1 << 14) /*!< ACMP0 wake-up configuration */ +#define SYSCTL_SLPWAKE_ACMP2_PD (1 << 15) /*!< ACMP0 wake-up configuration */ +#define SYSCTL_SLPWAKE_ACMP3_PD (1 << 16) /*!< ACMP0 wake-up configuration */ +#define SYSCTL_SLPWAKE_IREF_PD (1 << 17) /*!< Internal voltage reference wake-up configuration */ +#define SYSCTL_SLPWAKE_TS_PD (1 << 18) /*!< Temperature sensor wake-up configuration */ +#define SYSCTL_SLPWAKE_VDDADIV_PD (1 << 19) /*!< VDDA divider wake-up configuration */ +#define SYSCTL_SLPWAKE_WDTOSC_PD (1 << 20) /*!< Watchdog oscillator wake-up configuration */ +#define SYSCTL_SLPWAKE_SYSOSC_PD (1 << 21) /*!< System oscillator wake-up configuration */ +#define SYSCTL_SLPWAKE_SYSPLL_PD (1 << 22) /*!< System PLL wake-up configuration */ +#define SYSCTL_SLPWAKE_USBPLL_PD (1 << 23) /*!< USB PLL wake-up configuration */ +#define SYSCTL_SLPWAKE_SCTPLL_PD (1 << 24) /*!< SCT PLL wake-up configuration */ + +/** + * @brief Setup wakeup behaviour from deep sleep + * @param wakeupmask : OR'ed values of SYSCTL_SLPWAKE_* values (high is powered down) + * @return Nothing + * @note This must be setup prior to using deep sleep. See the user manual + * (PDWAKECFG register) for more info on setting this up. This function selects + * which peripherals are powered up on exit from deep sleep. + * This function should only be called once with all options for wakeup + * in that call. + */ +void Chip_SYSCTL_SetWakeup(uint32_t wakeupmask); + +/** + * @brief Return current wakeup mask + * @return OR'ed values of SYSCTL_SLPWAKE_* values + * @note A high state indicates the peripehral will powerup on wakeup. + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetWakeup(void) +{ + return LPC_SYSCTL->PDWAKECFG; +} + +/** + * Power down configuration values + */ +#define SYSCTL_POWERDOWN_TBD0_PD (1 << 0) /*!< TBD0 wake-up power down */ +#define SYSCTL_POWERDOWN_TBD1_PD (1 << 1) /*!< TBD1 wake-up power down */ +#define SYSCTL_POWERDOWN_TBD2_PD (1 << 2) /*!< TBD2 wake-up power down */ +#define SYSCTL_POWERDOWN_IRCOUT_PD (1 << 3) /*!< IRC oscillator output wake-up power down */ +#define SYSCTL_POWERDOWN_IRC_PD (1 << 4) /*!< IRC oscillator power-down wake-up power down */ +#define SYSCTL_POWERDOWN_FLASH_PD (1 << 5) /*!< Flash wake-up power down */ +#define SYSCTL_POWERDOWN_EEPROM_PD (1 << 6) /*!< EEPROM wake-up power down */ +#define SYSCTL_POWERDOWN_BOD_PD (1 << 8) /*!< BOD wake-up power down */ +#define SYSCTL_POWERDOWN_USBPHY_PD (1 << 9) /*!< USB PHY wake-up power down */ +#define SYSCTL_POWERDOWN_ADC0_PD (1 << 10) /*!< ADC0 wake-up power down */ +#define SYSCTL_POWERDOWN_ADC1_PD (1 << 11) /*!< ADC1 wake-up power down */ +#define SYSCTL_POWERDOWN_DAC_PD (1 << 12) /*!< DAC wake-up power down */ +#define SYSCTL_POWERDOWN_ACMP0_PD (1 << 13) /*!< ACMP0 wake-up power down */ +#define SYSCTL_POWERDOWN_ACMP1_PD (1 << 14) /*!< ACMP0 wake-up power down */ +#define SYSCTL_POWERDOWN_ACMP2_PD (1 << 15) /*!< ACMP0 wake-up power down */ +#define SYSCTL_POWERDOWN_ACMP3_PD (1 << 16) /*!< ACMP0 wake-up power down */ +#define SYSCTL_POWERDOWN_IREF_PD (1 << 17) /*!< Internal voltage reference wake-up power down */ +#define SYSCTL_POWERDOWN_TS_PD (1 << 18) /*!< Temperature sensor wake-up power down */ +#define SYSCTL_POWERDOWN_VDDADIV_PD (1 << 19) /*!< VDDA divider wake-up power down */ +#define SYSCTL_POWERDOWN_WDTOSC_PD (1 << 20) /*!< Watchdog oscillator wake-up power down */ +#define SYSCTL_POWERDOWN_SYSOSC_PD (1 << 21) /*!< System oscillator wake-up power down */ +#define SYSCTL_POWERDOWN_SYSPLL_PD (1 << 22) /*!< System PLL wake-up power down */ +#define SYSCTL_POWERDOWN_USBPLL_PD (1 << 23) /*!< USB PLL wake-up power down */ +#define SYSCTL_POWERDOWN_SCTPLL_PD (1 << 24) /*!< SCT PLL wake-up power down */ + +/** + * @brief Power down one or more blocks or peripherals + * @param powerdownmask : OR'ed values of SYSCTL_POWERDOWN_* values + * @return Nothing + */ +void Chip_SYSCTL_PowerDown(uint32_t powerdownmask); + +/** + * @brief Power up one or more blocks or peripherals + * @param powerupmask : OR'ed values of SYSCTL_POWERDOWN_* values + * @return Nothing + */ +void Chip_SYSCTL_PowerUp(uint32_t powerupmask); + +/** + * @brief Get power status + * @return OR'ed values of SYSCTL_POWERDOWN_* values + * @note A high state indicates the peripheral is powered down. + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetPowerStates(void) +{ + return LPC_SYSCTL->PDRUNCFG; +} + +/** + * @brief Return the JTAG ID code + * @return the JTAG ID code + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetJTAGIDCode(void) +{ + return LPC_SYSCTL->JTAG_IDCODE; +} + +/** + * @brief Return the device ID + * @param index : Index of device ID to get, 0 or 1 + * @return the device ID + */ +STATIC INLINE uint32_t Chip_SYSCTL_GetDeviceID(int index) +{ + return LPC_SYSCTL->DEVICEID[index]; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*!< __SYSCTL_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/uart_15xx.h b/lpc_chip_15xx/inc/uart_15xx.h new file mode 100644 index 0000000..8b0bb72 --- /dev/null +++ b/lpc_chip_15xx/inc/uart_15xx.h @@ -0,0 +1,436 @@ +/* + * @brief LPC15XX USART0/1/2 driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __UART_15XX_H_ +#define __UART_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ring_buffer.h" + +/** @defgroup UART_15XX CHIP: LPC15xx USART Driver (UARTS 0/1/2) + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief UART register block structure + */ +typedef struct { + __IO uint32_t CFG; /*!< Configuration register */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t STAT; /*!< Status register */ + __IO uint32_t INTENSET; /*!< Interrupt Enable read and set register */ + __O uint32_t INTENCLR; /*!< Interrupt Enable clear register */ + __I uint32_t RXDATA; /*!< Receive Data register */ + __I uint32_t RXDATA_STAT; /*!< Receive Data with status register */ + __IO uint32_t TXDATA; /*!< Transmit data register */ + __IO uint32_t BRG; /*!< Baud Rate Generator register */ + __IO uint32_t INTSTAT; /*!< Interrupt status register */ +} LPC_USART_T; + +/** + * @brief UART CFG register definitions + */ +#define UART_CFG_ENABLE (0x01 << 0) +#define UART_CFG_DATALEN_7 (0x00 << 2) /*!< UART 7 bit length mode */ +#define UART_CFG_DATALEN_8 (0x01 << 2) /*!< UART 8 bit length mode */ +#define UART_CFG_DATALEN_9 (0x02 << 2) /*!< UART 9 bit length mode */ +#define UART_CFG_PARITY_NONE (0x00 << 4) /*!< No parity */ +#define UART_CFG_PARITY_EVEN (0x02 << 4) /*!< Even parity */ +#define UART_CFG_PARITY_ODD (0x03 << 4) /*!< Odd parity */ +#define UART_CFG_STOPLEN_1 (0x00 << 6) /*!< UART One Stop Bit Select */ +#define UART_CFG_STOPLEN_2 (0x01 << 6) /*!< UART Two Stop Bits Select */ +#define UART_MODE_32K (0x01 << 7) /*!< Selects the 32 kHz clock from the RTC oscillator as the clock source to the BRG */ +#define UART_CFG_CTSEN (0x01 << 9) /*!< CTS enable bit */ +#define UART_CFG_SYNCEN (0x01 << 11) /*!< Synchronous mode enable bit */ +#define UART_CFG_CLKPOL (0x01 << 12) /*!< Un_RXD rising edge sample enable bit */ +#define UART_CFG_SYNCMST (0x01 << 14) /*!< Select master mode (synchronous mode) enable bit */ +#define UART_CFG_LOOP (0x01 << 15) /*!< Loopback mode enable bit */ + +/** + * @brief UART CTRL register definitions + */ +#define UART_CTRL_TXBRKEN (0x01 << 1) /*!< Continuous break enable bit */ +#define UART_CTRL_ADDRDET (0x01 << 2) /*!< Address detect mode enable bit */ +#define UART_CTRL_TXDIS (0x01 << 6) /*!< Transmit disable bit */ +#define UART_CTRL_CC (0x01 << 8) /*!< Continuous Clock mode enable bit */ +#define UART_CTRL_CLRCC (0x01 << 9) /*!< Clear Continuous Clock bit */ + +/** + * @brief UART STAT register definitions + */ +#define UART_STAT_RXRDY (0x01 << 0) /*!< Receiver ready */ +#define UART_STAT_RXIDLE (0x01 << 1) /*!< Receiver idle */ +#define UART_STAT_TXRDY (0x01 << 2) /*!< Transmitter ready for data */ +#define UART_STAT_TXIDLE (0x01 << 3) /*!< Transmitter idle */ +#define UART_STAT_CTS (0x01 << 4) /*!< Status of CTS signal */ +#define UART_STAT_DELTACTS (0x01 << 5) /*!< Change in CTS state */ +#define UART_STAT_TXDISINT (0x01 << 6) /*!< Transmitter disabled */ +#define UART_STAT_OVERRUNINT (0x01 << 8) /*!< Overrun Error interrupt flag. */ +#define UART_STAT_RXBRK (0x01 << 10) /*!< Received break */ +#define UART_STAT_DELTARXBRK (0x01 << 11) /*!< Change in receive break detection */ +#define UART_STAT_START (0x01 << 12) /*!< Start detected */ +#define UART_STAT_FRM_ERRINT (0x01 << 13) /*!< Framing Error interrupt flag */ +#define UART_STAT_PAR_ERRINT (0x01 << 14) /*!< Parity Error interrupt flag */ +#define UART_STAT_RXNOISEINT (0x01 << 15) /*!< Received Noise interrupt flag */ + +/** + * @brief UART INTENSET/INTENCLR register definitions + */ +#define UART_INTEN_RXRDY (0x01 << 0) /*!< Receive Ready interrupt */ +#define UART_INTEN_TXRDY (0x01 << 2) /*!< Transmit Ready interrupt */ +#define UART_INTEN_DELTACTS (0x01 << 5) /*!< Change in CTS state interrupt */ +#define UART_INTEN_TXDIS (0x01 << 6) /*!< Transmitter disable interrupt */ +#define UART_INTEN_OVERRUN (0x01 << 8) /*!< Overrun error interrupt */ +#define UART_INTEN_DELTARXBRK (0x01 << 11) /*!< Change in receiver break detection interrupt */ +#define UART_INTEN_START (0x01 << 12) /*!< Start detect interrupt */ +#define UART_INTEN_FRAMERR (0x01 << 13) /*!< Frame error interrupt */ +#define UART_INTEN_PARITYERR (0x01 << 14) /*!< Parity error interrupt */ +#define UART_INTEN_RXNOISE (0x01 << 15) /*!< Received noise interrupt */ + +/** + * @brief Enable the UART + * @param pUART : Pointer to selected UARTx peripheral + * @return Nothing + */ +STATIC INLINE void Chip_UART_Enable(LPC_USART_T *pUART) +{ + pUART->CFG |= UART_CFG_ENABLE; +} + +/** + * @brief Disable the UART + * @param pUART : Pointer to selected UARTx peripheral + * @return Nothing + */ +STATIC INLINE void Chip_UART_Disable(LPC_USART_T *pUART) +{ + pUART->CFG &= ~UART_CFG_ENABLE; +} + +/** + * @brief Enable transmission on UART TxD pin + * @param pUART : Pointer to selected pUART peripheral + * @return Nothing + */ +STATIC INLINE void Chip_UART_TXEnable(LPC_USART_T *pUART) +{ + pUART->CTRL &= ~UART_CTRL_TXDIS; +} + +/** + * @brief Disable transmission on UART TxD pin + * @param pUART : Pointer to selected pUART peripheral + * @return Nothing + */ +STATIC INLINE void Chip_UART_TXDisable(LPC_USART_T *pUART) +{ + pUART->CTRL |= UART_CTRL_TXDIS; +} + +/** + * @brief Transmit a single data byte through the UART peripheral + * @param pUART : Pointer to selected UART peripheral + * @param data : Byte to transmit + * @return Nothing + * @note This function attempts to place a byte into the UART transmit + * holding register regard regardless of UART state. + */ +STATIC INLINE void Chip_UART_SendByte(LPC_USART_T *pUART, uint8_t data) +{ + pUART->TXDATA = (uint32_t) data; +} + +/** + * @brief Read a single byte data from the UART peripheral + * @param pUART : Pointer to selected UART peripheral + * @return A single byte of data read + * @note This function reads a byte from the UART receive FIFO or + * receive hold register regard regardless of UART state. The + * FIFO status should be read first prior to using this function + */ +STATIC INLINE uint32_t Chip_UART_ReadByte(LPC_USART_T *pUART) +{ + /* Strip off undefined reserved bits, keep 9 lower bits */ + return (uint32_t) (pUART->RXDATA & 0x000001FF); +} + +/** + * @brief Enable UART interrupts + * @param pUART : Pointer to selected UART peripheral + * @param intMask : OR'ed Interrupts to enable + * @return Nothing + * @note Use an OR'ed value of UART_INTEN_* definitions with this function + * to enable specific UART interrupts. + */ +STATIC INLINE void Chip_UART_IntEnable(LPC_USART_T *pUART, uint32_t intMask) +{ + pUART->INTENSET = intMask; +} + +/** + * @brief Disable UART interrupts + * @param pUART : Pointer to selected UART peripheral + * @param intMask : OR'ed Interrupts to disable + * @return Nothing + * @note Use an OR'ed value of UART_INTEN_* definitions with this function + * to disable specific UART interrupts. + */ +STATIC INLINE void Chip_UART_IntDisable(LPC_USART_T *pUART, uint32_t intMask) +{ + pUART->INTENCLR = intMask; +} + +/** + * @brief Returns UART interrupts that are enabled + * @param pUART : Pointer to selected UART peripheral + * @return Returns the enabled UART interrupts + * @note Use an OR'ed value of UART_INTEN_* definitions with this function + * to determine which interrupts are enabled. You can check + * for multiple enabled bits if needed. + */ +STATIC INLINE uint32_t Chip_UART_GetIntsEnabled(LPC_USART_T *pUART) +{ + return pUART->INTENSET; +} + +/** + * @brief Get UART interrupt status + * @param pUART : The base of UART peripheral on the chip + * @return The Interrupt status register of UART + * @note Multiple interrupts may be pending. Mask the return value + * with one or more UART_INTEN_* definitions to determine + * pending interrupts. + */ +STATIC INLINE uint32_t Chip_UART_GetIntStatus(LPC_USART_T *pUART) +{ + return pUART->INTSTAT; +} + +/** + * @brief Configure data width, parity and stop bits + * @param pUART : Pointer to selected pUART peripheral + * @param config : UART configuration, OR'ed values of select UART_CFG_* defines + * @return Nothing + * @note Select OR'ed config options for the UART from the UART_CFG_PARITY_*, + * UART_CFG_STOPLEN_*, and UART_CFG_DATALEN_* definitions. For example, + * a configuration of 8 data bits, 1 stop bit, and even (enabled) parity would be + * (UART_CFG_DATALEN_8 | UART_CFG_STOPLEN_1 | UART_CFG_PARITY_EVEN). Will not + * alter other bits in the CFG register. + */ +STATIC INLINE void Chip_UART_ConfigData(LPC_USART_T *pUART, uint32_t config) +{ + uint32_t reg; + + reg = pUART->CFG & ~((0x3 << 2) | (0x3 << 4) | (0x1 << 6)); + pUART->CFG = reg | config; +} + +/** + * @brief Get the UART status register + * @param pUART : Pointer to selected UARTx peripheral + * @return UART status register + * @note Multiple statuses may be pending. Mask the return value + * with one or more UART_STAT_* definitions to determine + * statuses. + */ +STATIC INLINE uint32_t Chip_UART_GetStatus(LPC_USART_T *pUART) +{ + return pUART->STAT; +} + +/** + * @brief Clear the UART status register + * @param pUART : Pointer to selected UARTx peripheral + * @param stsMask : OR'ed statuses to disable + * @return Nothing + * @note Multiple interrupts may be pending. Mask the return value + * with one or more UART_INTEN_* definitions to determine + * pending interrupts. + */ +STATIC INLINE void Chip_UART_ClearStatus(LPC_USART_T *pUART, uint32_t stsMask) +{ + pUART->STAT = stsMask; +} + +/** + * @brief Initialize the UART peripheral + * @param pUART : The base of UART peripheral on the chip + * @return Nothing + */ +void Chip_UART_Init(LPC_USART_T *pUART); + +/** + * @brief Deinitialize the UART peripheral + * @param pUART : The base of UART peripheral on the chip + * @return Nothing + */ +void Chip_UART_DeInit(LPC_USART_T *pUART); + +/** + * @brief Transmit a byte array through the UART peripheral (non-blocking) + * @param pUART : Pointer to selected UART peripheral + * @param data : Pointer to bytes to transmit + * @param numBytes : Number of bytes to transmit + * @return The actual number of bytes placed into the FIFO + * @note This function places data into the transmit FIFO until either + * all the data is in the FIFO or the FIFO is full. This function + * will not block in the FIFO is full. The actual number of bytes + * placed into the FIFO is returned. This function ignores errors. + */ +int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes); + +/** + * @brief Read data through the UART peripheral (non-blocking) + * @param pUART : Pointer to selected UART peripheral + * @param data : Pointer to bytes array to fill + * @param numBytes : Size of the passed data array + * @return The actual number of bytes read + * @note This function reads data from the receive FIFO until either + * all the data has been read or the passed buffer is completely full. + * This function will not block. This function ignores errors. + */ +int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes); + +/** + * @brief Set baud rate for UART + * @param pUART : The base of UART peripheral on the chip + * @param baudrate: Baud rate to be set + * @return Nothing + */ +void Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate); + +/** + * @brief Set baud rate for UART using RTC32K oscillator + * @param pUART : The base of UART peripheral on the chip + * @param baudrate: Baud rate to be set + * @return Nothing + * @note Since the baud rate is divided from the 32KHz oscillator, + * this function should only be used with baud rates less + * than or equal to 9600 baud. Don't expect any accuracy. + */ +void Chip_UART_SetBaudWithRTC32K(LPC_USART_T *pUART, uint32_t baudrate); + +/** + * @brief Transmit a byte array through the UART peripheral (blocking) + * @param pUART : Pointer to selected UART peripheral + * @param data : Pointer to data to transmit + * @param numBytes : Number of bytes to transmit + * @return The number of bytes transmitted + * @note This function will send or place all bytes into the transmit + * FIFO. This function will block until the last bytes are in the FIFO. + */ +int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes); + +/** + * @brief Read data through the UART peripheral (blocking) + * @param pUART : Pointer to selected UART peripheral + * @param data : Pointer to data array to fill + * @param numBytes : Size of the passed data array + * @return The size of the dat array + * @note This function reads data from the receive FIFO until the passed + * buffer is completely full. The function will block until full. + * This function ignores errors. + */ +int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes); + +/** + * @brief UART receive-only interrupt handler for ring buffers + * @param pUART : Pointer to selected UART peripheral + * @param pRB : Pointer to ring buffer structure to use + * @return Nothing + * @note If ring buffer support is desired for the receive side + * of data transfer, the UART interrupt should call this + * function for a receive based interrupt status. + */ +void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB); + +/** + * @brief UART transmit-only interrupt handler for ring buffers + * @param pUART : Pointer to selected UART peripheral + * @param pRB : Pointer to ring buffer structure to use + * @return Nothing + * @note If ring buffer support is desired for the transmit side + * of data transfer, the UART interrupt should call this + * function for a transmit based interrupt status. + */ +void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB); + +/** + * @brief Populate a transmit ring buffer and start UART transmit + * @param pUART : Pointer to selected UART peripheral + * @param pRB : Pointer to ring buffer structure to use + * @param data : Pointer to buffer to move to ring buffer + * @param count : Number of bytes to move + * @return The number of bytes placed into the ring buffer + * @note Will move the data into the TX ring buffer and start the + * transfer. If the number of bytes returned is less than the + * number of bytes to send, the ring buffer is considered full. + */ +uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int count); + +/** + * @brief Copy data from a receive ring buffer + * @param pUART : Pointer to selected UART peripheral + * @param pRB : Pointer to ring buffer structure to use + * @param data : Pointer to buffer to fill from ring buffer + * @param bytes : Size of the passed buffer in bytes + * @return The number of bytes placed into the ring buffer + * @note Will move the data from the RX ring buffer up to the + * the maximum passed buffer size. Returns 0 if there is + * no data in the ring buffer. + */ +int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes); + +/** + * @brief UART receive/transmit interrupt handler for ring buffers + * @param pUART : Pointer to selected UART peripheral + * @param pRXRB : Pointer to transmit ring buffer + * @param pTXRB : Pointer to receive ring buffer + * @return Nothing + * @note This provides a basic implementation of the UART IRQ + * handler for support of a ring buffer implementation for + * transmit and receive. + */ +void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __UART_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd.h b/lpc_chip_15xx/inc/usbd/usbd.h new file mode 100644 index 0000000..96ed977 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd.h @@ -0,0 +1,705 @@ +/*********************************************************************** +* $Id:: mw_usbd.h 575 2012-11-20 01:35:56Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef __USBD_H__ +#define __USBD_H__ + +/** \file + * \brief Common definitions and declarations for the USB stack. + * + * Common definitions and declarations for the USB stack. + * \addtogroup USBD_Core + * @{ + */ + +#include "lpc_types.h" + +#if defined(__GNUC__) +/* As per http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax, +6.29 Attributes Syntax +"An attribute specifier list may appear as part of a struct, union or +enum specifier. It may go either immediately after the struct, union +or enum keyword, or after the closing brace. The former syntax is +preferred. Where attribute specifiers follow the closing brace, they +are considered to relate to the structure, union or enumerated type +defined, not to any enclosing declaration the type specifier appears +in, and the type defined is not complete until after the attribute +specifiers." +So use POST_PACK immediately after struct keyword +*/ +#define PRE_PACK +#define POST_PACK __attribute__((__packed__)) +#define ALIGNED(n) __attribute__((aligned (n))) + +#elif defined(__arm) +#define PRE_PACK __packed +#define POST_PACK +#define ALIGNED(n) __align(n) + +#elif defined(__ICCARM__) +#define PRE_PACK __packed +#define POST_PACK +#define PRAGMA_ALIGN_4096 _Pragma("data_alignment=4096") +#define PRAGMA_ALIGN_2048 _Pragma("data_alignment=2048") +#define PRAGMA_ALIGN_512 _Pragma("data_alignment=512") +#define PRAGMA_ALIGN_256 _Pragma("data_alignment=256") +#define PRAGMA_ALIGN_128 _Pragma("data_alignment=128") +#define PRAGMA_ALIGN_64 _Pragma("data_alignment=64") +#define PRAGMA_ALIGN_48 _Pragma("data_alignment=48") +#define PRAGMA_ALIGN_32 _Pragma("data_alignment=32") +#define PRAGMA_ALIGN_4 _Pragma("data_alignment=4") +#define ALIGNED(n) PRAGMA_ALIGN_##n + +#pragma diag_suppress=Pe021 +#endif + +/** Structure to pack lower and upper byte to form 16 bit word. */ +PRE_PACK struct POST_PACK _WB_T +{ + uint8_t L; /**< lower byte */ + uint8_t H; /**< upper byte */ +}; +/** Structure to pack lower and upper byte to form 16 bit word.*/ +typedef struct _WB_T WB_T; + +/** Union of \ref _WB_T struct and 16 bit word.*/ +PRE_PACK union POST_PACK __WORD_BYTE +{ + uint16_t W; /**< data member to do 16 bit access */ + WB_T WB; /**< data member to do 8 bit access */ +} ; +/** Union of \ref _WB_T struct and 16 bit word.*/ +typedef union __WORD_BYTE WORD_BYTE; + +/** bmRequestType.Dir defines + * @{ + */ +/** Request from host to device */ +#define REQUEST_HOST_TO_DEVICE 0 +/** Request from device to host */ +#define REQUEST_DEVICE_TO_HOST 1 +/** @} */ + +/** bmRequestType.Type defines + * @{ + */ +/** Standard Request */ +#define REQUEST_STANDARD 0 +/** Class Request */ +#define REQUEST_CLASS 1 +/** Vendor Request */ +#define REQUEST_VENDOR 2 +/** Reserved Request */ +#define REQUEST_RESERVED 3 +/** @} */ + +/** bmRequestType.Recipient defines + * @{ + */ +/** Request to device */ +#define REQUEST_TO_DEVICE 0 +/** Request to interface */ +#define REQUEST_TO_INTERFACE 1 +/** Request to endpoint */ +#define REQUEST_TO_ENDPOINT 2 +/** Request to other */ +#define REQUEST_TO_OTHER 3 +/** @} */ + +/** Structure to define 8 bit USB request.*/ +PRE_PACK struct POST_PACK _BM_T +{ + uint8_t Recipient : 5; /**< Recipient type. */ + uint8_t Type : 2; /**< Request type. */ + uint8_t Dir : 1; /**< Direction type. */ +}; +/** Structure to define 8 bit USB request.*/ +typedef struct _BM_T BM_T; + +/** Union of \ref _BM_T struct and 8 bit byte.*/ +PRE_PACK union POST_PACK _REQUEST_TYPE +{ + uint8_t B; /**< byte wide access memeber */ + BM_T BM; /**< bitfield structure access memeber */ +} ; +/** Union of \ref _BM_T struct and 8 bit byte.*/ +typedef union _REQUEST_TYPE REQUEST_TYPE; + +/** USB Standard Request Codes + * @{ + */ +/** GET_STATUS request */ +#define USB_REQUEST_GET_STATUS 0 +/** CLEAR_FEATURE request */ +#define USB_REQUEST_CLEAR_FEATURE 1 +/** SET_FEATURE request */ +#define USB_REQUEST_SET_FEATURE 3 +/** SET_ADDRESS request */ +#define USB_REQUEST_SET_ADDRESS 5 +/** GET_DESCRIPTOR request */ +#define USB_REQUEST_GET_DESCRIPTOR 6 +/** SET_DESCRIPTOR request */ +#define USB_REQUEST_SET_DESCRIPTOR 7 +/** GET_CONFIGURATION request */ +#define USB_REQUEST_GET_CONFIGURATION 8 +/** SET_CONFIGURATION request */ +#define USB_REQUEST_SET_CONFIGURATION 9 +/** GET_INTERFACE request */ +#define USB_REQUEST_GET_INTERFACE 10 +/** SET_INTERFACE request */ +#define USB_REQUEST_SET_INTERFACE 11 +/** SYNC_FRAME request */ +#define USB_REQUEST_SYNC_FRAME 12 +/** @} */ + +/** USB GET_STATUS Bit Values + * @{ + */ +/** SELF_POWERED status*/ +#define USB_GETSTATUS_SELF_POWERED 0x01 +/** REMOTE_WAKEUP capable status*/ +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +/** ENDPOINT_STALL status*/ +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 +/** @} */ + +/** USB Standard Feature selectors + * @{ + */ +/** ENDPOINT_STALL feature*/ +#define USB_FEATURE_ENDPOINT_STALL 0 +/** REMOTE_WAKEUP feature*/ +#define USB_FEATURE_REMOTE_WAKEUP 1 +/** TEST_MODE feature*/ +#define USB_FEATURE_TEST_MODE 2 +/** @} */ + +/** USB Default Control Pipe Setup Packet*/ +PRE_PACK struct POST_PACK _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; /**< This bitmapped field identifies the characteristics + of the specific request. \sa _BM_T. + */ + uint8_t bRequest; /**< This field specifies the particular request. The + Type bits in the bmRequestType field modify the meaning + of this field. \sa USBD_REQUEST. + */ + WORD_BYTE wValue; /**< Used to pass a parameter to the device, specific + to the request. + */ + WORD_BYTE wIndex; /**< Used to pass a parameter to the device, specific + to the request. The wIndex field is often used in + requests to specify an endpoint or an interface. + */ + uint16_t wLength; /**< This field specifies the length of the data + transferred during the second phase of the control + transfer. + */ +} ; +/** USB Default Control Pipe Setup Packet*/ +typedef struct _USB_SETUP_PACKET USB_SETUP_PACKET; + + +/** USB Descriptor Types + * @{ + */ +/** Device descriptor type */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +/** Configuration descriptor type */ +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +/** String descriptor type */ +#define USB_STRING_DESCRIPTOR_TYPE 3 +/** Interface descriptor type */ +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +/** Endpoint descriptor type */ +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +/** Device qualifier descriptor type */ +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +/** Other speed configuration descriptor type */ +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +/** Interface power descriptor type */ +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +/** OTG descriptor type */ +#define USB_OTG_DESCRIPTOR_TYPE 9 +/** Debug descriptor type */ +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +/** Interface association descriptor type */ +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 +/** @} */ + +/** USB Device Classes + * @{ + */ +/** Reserved device class */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +/** Audio device class */ +#define USB_DEVICE_CLASS_AUDIO 0x01 +/** Communications device class */ +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +/** Human interface device class */ +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +/** monitor device class */ +#define USB_DEVICE_CLASS_MONITOR 0x04 +/** physical interface device class */ +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +/** power device class */ +#define USB_DEVICE_CLASS_POWER 0x06 +/** Printer device class */ +#define USB_DEVICE_CLASS_PRINTER 0x07 +/** Storage device class */ +#define USB_DEVICE_CLASS_STORAGE 0x08 +/** Hub device class */ +#define USB_DEVICE_CLASS_HUB 0x09 +/** miscellaneous device class */ +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +/** Application device class */ +#define USB_DEVICE_CLASS_APP 0xFE +/** Vendor specific device class */ +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF +/** @} */ + +/** bmAttributes in Configuration Descriptor + * @{ + */ +/** Power field mask */ +#define USB_CONFIG_POWERED_MASK 0x40 +/** Bus powered */ +#define USB_CONFIG_BUS_POWERED 0x80 +/** Self powered */ +#define USB_CONFIG_SELF_POWERED 0xC0 +/** remote wakeup */ +#define USB_CONFIG_REMOTE_WAKEUP 0x20 +/** @} */ + +/** bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/** bEndpointAddress in Endpoint Descriptor + * @{ + */ +/** Endopint address mask */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +/** Macro to convert OUT endopint number to endpoint address value. */ +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +/** Macro to convert IN endopint number to endpoint address value. */ +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) +/** @} */ + +/** bmAttributes in Endpoint Descriptor + * @{ + */ +/** Endopint type mask */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +/** Control Endopint type */ +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +/** isochronous Endopint type */ +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +/** bulk Endopint type */ +#define USB_ENDPOINT_TYPE_BULK 0x02 +/** interrupt Endopint type */ +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +/** Endopint sync type mask */ +#define USB_ENDPOINT_SYNC_MASK 0x0C +/** no synchronization Endopint */ +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +/** Asynchronous sync Endopint */ +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +/** Adaptive sync Endopint */ +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +/** Synchronous sync Endopint */ +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +/** Endopint usage type mask */ +#define USB_ENDPOINT_USAGE_MASK 0x30 +/** Endopint data usage type */ +#define USB_ENDPOINT_USAGE_DATA 0x00 +/** Endopint feedback usage type */ +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +/** Endopint implicit feedback usage type */ +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +/** Endopint reserved usage type */ +#define USB_ENDPOINT_USAGE_RESERVED 0x30 +/** @} */ + +/** Control endopint EP0's maximum packet size in high-speed mode.*/ +#define USB_ENDPOINT_0_HS_MAXP 64 +/** Control endopint EP0's maximum packet size in low-speed mode.*/ +#define USB_ENDPOINT_0_LS_MAXP 8 +/** Bulk endopint's maximum packet size in high-speed mode.*/ +#define USB_ENDPOINT_BULK_HS_MAXP 512 + +/** USB Standard Device Descriptor */ +PRE_PACK struct POST_PACK _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes. */ + uint8_t bDescriptorType; /**< DEVICE Descriptor Type. */ + uint16_t bcdUSB; /**< BUSB Specification Release Number in + Binary-Coded Decimal (i.e., 2.10 is 210H). + This field identifies the release of the USB + Specification with which the device and its + descriptors are compliant. + */ + uint8_t bDeviceClass; /**< Class code (assigned by the USB-IF). + If this field is reset to zero, each interface + within a configuration specifies its own + class information and the various + interfaces operate independently.\n + If this field is set to a value between 1 and + FEH, the device supports different class + specifications on different interfaces and + the interfaces may not operate + independently. This value identifies the + class definition used for the aggregate + interfaces. \n + If this field is set to FFH, the device class + is vendor-specific. + */ + uint8_t bDeviceSubClass; /**< Subclass code (assigned by the USB-IF). + These codes are qualified by the value of + the bDeviceClass field. \n + If the bDeviceClass field is reset to zero, + this field must also be reset to zero. \n + If the bDeviceClass field is not set to FFH, + all values are reserved for assignment by + the USB-IF. + */ + uint8_t bDeviceProtocol; /**< Protocol code (assigned by the USB-IF). + These codes are qualified by the value of + the bDeviceClass and the + bDeviceSubClass fields. If a device + supports class-specific protocols on a + device basis as opposed to an interface + basis, this code identifies the protocols + that the device uses as defined by the + specification of the device class. \n + If this field is reset to zero, the device + does not use class-specific protocols on a + device basis. However, it may use classspecific + protocols on an interface basis. \n + If this field is set to FFH, the device uses a + vendor-specific protocol on a device basis. + */ + uint8_t bMaxPacketSize0; /**< Maximum packet size for endpoint zero + (only 8, 16, 32, or 64 are valid). For HS devices + is fixed to 64. + */ + + uint16_t idVendor; /**< Vendor ID (assigned by the USB-IF). */ + uint16_t idProduct; /**< Product ID (assigned by the manufacturer). */ + uint16_t bcdDevice; /**< Device release number in binary-coded decimal. */ + uint8_t iManufacturer; /**< Index of string descriptor describing manufacturer. */ + uint8_t iProduct; /**< Index of string descriptor describing product. */ + uint8_t iSerialNumber; /**< Index of string descriptor describing the device’s + serial number. + */ + uint8_t bNumConfigurations; /**< Number of possible configurations. */ +} ; +/** USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR; + +/** USB 2.0 Device Qualifier Descriptor */ +PRE_PACK struct POST_PACK _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; /**< Size of descriptor */ + uint8_t bDescriptorType; /**< Device Qualifier Type */ + uint16_t bcdUSB; /**< USB specification version number (e.g., 0200H for V2.00) */ + uint8_t bDeviceClass; /**< Class Code */ + uint8_t bDeviceSubClass; /**< SubClass Code */ + uint8_t bDeviceProtocol; /**< Protocol Code */ + uint8_t bMaxPacketSize0; /**< Maximum packet size for other speed */ + uint8_t bNumConfigurations; /**< Number of Other-speed Configurations */ + uint8_t bReserved; /**< Reserved for future use, must be zero */ +} ; +/** USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/** USB Standard Configuration Descriptor */ +PRE_PACK struct POST_PACK _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /**< CONFIGURATION Descriptor Type*/ + uint16_t wTotalLength; /**< Total length of data returned for this + configuration. Includes the combined length + of all descriptors (configuration, interface, + endpoint, and class- or vendor-specific) + returned for this configuration.*/ + uint8_t bNumInterfaces; /**< Number of interfaces supported by this configuration*/ + uint8_t bConfigurationValue; /**< Value to use as an argument to the + SetConfiguration() request to select this + configuration. */ + uint8_t iConfiguration; /**< Index of string descriptor describing this + configuration*/ + uint8_t bmAttributes; /**< Configuration characteristics \n + D7: Reserved (set to one)\n + D6: Self-powered \n + D5: Remote Wakeup \n + D4...0: Reserved (reset to zero) \n + D7 is reserved and must be set to one for + historical reasons. \n + A device configuration that uses power from + the bus and a local source reports a non-zero + value in bMaxPower to indicate the amount of + bus power required and sets D6. The actual + power source at runtime may be determined + using the GetStatus(DEVICE) request (see + USB 2.0 spec Section 9.4.5). \n + If a device configuration supports remote + wakeup, D5 is set to one.*/ + uint8_t bMaxPower; /**< Maximum power consumption of the USB + device from the bus in this specific + configuration when the device is fully + operational. Expressed in 2 mA units + (i.e., 50 = 100 mA). \n + Note: A device configuration reports whether + the configuration is bus-powered or selfpowered. + Device status reports whether the + device is currently self-powered. If a device is + disconnected from its external power source, it + updates device status to indicate that it is no + longer self-powered. \n + A device may not increase its power draw + from the bus, when it loses its external power + source, beyond the amount reported by its + configuration. \n + If a device can continue to operate when + disconnected from its external power source, it + continues to do so. If the device cannot + continue to operate, it fails operations it can + no longer support. The USB System Software + may determine the cause of the failure by + checking the status and noting the loss of the + device’s power source.*/ +} ; +/** USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR USB_CONFIGURATION_DESCRIPTOR; + +/** USB Standard Interface Association Descriptor */ +PRE_PACK struct POST_PACK _USB_IAD_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes*/ + uint8_t bDescriptorType; /**< INTERFACE ASSOCIATION Descriptor Type*/ + uint8_t bFirstInterface; /**< Interface number of the first interface that is + associated with this function.*/ + uint8_t bInterfaceCount; /**< Number of contiguous interfaces that are + associated with this function. */ + uint8_t bFunctionClass; /**< Class code (assigned by USB-IF). \n + A value of zero is not allowed in this descriptor. + If this field is FFH, the function class is vendorspecific. + All other values are reserved for assignment by + the USB-IF.*/ + uint8_t bFunctionSubClass; /**< Subclass code (assigned by USB-IF). \n + If the bFunctionClass field is not set to FFH all + values are reserved for assignment by the USBIF.*/ + uint8_t bFunctionProtocol; /**< Protocol code (assigned by the USB). \n + These codes are qualified by the values of the + bFunctionClass and bFunctionSubClass fields.*/ + uint8_t iFunction; /**< Index of string descriptor describing this function.*/ +} ; +/** USB Standard Interface Association Descriptor */ +typedef struct _USB_IAD_DESCRIPTOR USB_IAD_DESCRIPTOR; + +/** USB Standard Interface Descriptor */ +PRE_PACK struct POST_PACK _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes*/ + uint8_t bDescriptorType; /**< INTERFACE Descriptor Type*/ + uint8_t bInterfaceNumber; /**< Number of this interface. Zero-based + value identifying the index in the array of + concurrent interfaces supported by this + configuration.*/ + uint8_t bAlternateSetting; /**< Value used to select this alternate setting + for the interface identified in the prior field*/ + uint8_t bNumEndpoints; /**< Number of endpoints used by this + interface (excluding endpoint zero). If this + value is zero, this interface only uses the + Default Control Pipe.*/ + uint8_t bInterfaceClass; /**< Class code (assigned by the USB-IF). \n + A value of zero is reserved for future + standardization. \n + If this field is set to FFH, the interface + class is vendor-specific. \n + All other values are reserved for + assignment by the USB-IF.*/ + uint8_t bInterfaceSubClass; /**< Subclass code (assigned by the USB-IF). \n + These codes are qualified by the value of + the bInterfaceClass field. \n + If the bInterfaceClass field is reset to zero, + this field must also be reset to zero. \n + If the bInterfaceClass field is not set to + FFH, all values are reserved for + assignment by the USB-IF.*/ + uint8_t bInterfaceProtocol; /**< Protocol code (assigned by the USB). \n + These codes are qualified by the value of + the bInterfaceClass and the + bInterfaceSubClass fields. If an interface + supports class-specific requests, this code + identifies the protocols that the device + uses as defined by the specification of the + device class. \n + If this field is reset to zero, the device + does not use a class-specific protocol on + this interface. \n + If this field is set to FFH, the device uses + a vendor-specific protocol for this + interface.*/ + uint8_t iInterface; /**< Index of string descriptor describing this interface*/ +} ; +/** USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR USB_INTERFACE_DESCRIPTOR; + +/** USB Standard Endpoint Descriptor */ +PRE_PACK struct POST_PACK _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes*/ + uint8_t bDescriptorType; /**< ENDPOINT Descriptor Type*/ + uint8_t bEndpointAddress; /**< The address of the endpoint on the USB device + described by this descriptor. The address is + encoded as follows: \n + Bit 3...0: The endpoint number \n + Bit 6...4: Reserved, reset to zero \n + Bit 7: Direction, ignored for control endpoints + 0 = OUT endpoint + 1 = IN endpoint. \n \sa USBD_ENDPOINT_ADR_Type*/ + uint8_t bmAttributes; /**< This field describes the endpoint’s attributes when it is + configured using the bConfigurationValue. \n + Bits 1..0: Transfer Type + \li 00 = Control + \li 01 = Isochronous + \li 10 = Bulk + \li 11 = Interrupt \n + If not an isochronous endpoint, bits 5..2 are reserved + and must be set to zero. If isochronous, they are + defined as follows: \n + Bits 3..2: Synchronization Type + \li 00 = No Synchronization + \li 01 = Asynchronous + \li 10 = Adaptive + \li 11 = Synchronous \n + Bits 5..4: Usage Type + \li 00 = Data endpoint + \li 01 = Feedback endpoint + \li 10 = Implicit feedback Data endpoint + \li 11 = Reserved \n + Refer to Chapter 5 of USB 2.0 specification for more information. \n + All other bits are reserved and must be reset to zero. + Reserved bits must be ignored by the host. + \n \sa USBD_EP_ATTR_Type*/ + uint16_t wMaxPacketSize; /**< Maximum packet size this endpoint is capable of + sending or receiving when this configuration is + selected. \n + For isochronous endpoints, this value is used to + reserve the bus time in the schedule, required for the + per-(micro)frame data payloads. The pipe may, on an + ongoing basis, actually use less bandwidth than that + reserved. The device reports, if necessary, the actual + bandwidth used via its normal, non-USB defined + mechanisms. \n + For all endpoints, bits 10..0 specify the maximum + packet size (in bytes). \n + For high-speed isochronous and interrupt endpoints: \n + Bits 12..11 specify the number of additional transaction + opportunities per microframe: \n + \li 00 = None (1 transaction per microframe) + \li 01 = 1 additional (2 per microframe) + \li 10 = 2 additional (3 per microframe) + \li 11 = Reserved \n + Bits 15..13 are reserved and must be set to zero.*/ + uint8_t bInterval; /**< Interval for polling endpoint for data transfers. + Expressed in frames or microframes depending on the + device operating speed (i.e., either 1 millisecond or + 125 µs units). + \li For full-/high-speed isochronous endpoints, this value + must be in the range from 1 to 16. The bInterval value + is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a + bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). + \li For full-/low-speed interrupt endpoints, the value of + this field may be from 1 to 255. + \li For high-speed interrupt endpoints, the bInterval value + is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a + bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value + must be from 1 to 16. + \li For high-speed bulk/control OUT endpoints, the + bInterval must specify the maximum NAK rate of the + endpoint. A value of 0 indicates the endpoint never + NAKs. Other values indicate at most 1 NAK each + bInterval number of microframes. This value must be + in the range from 0 to 255. \n + Refer to Chapter 5 of USB 2.0 specification for more information. + */ +} ; +/** USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR USB_ENDPOINT_DESCRIPTOR; + +/** USB String Descriptor */ +PRE_PACK struct POST_PACK _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes*/ + uint8_t bDescriptorType; /**< STRING Descriptor Type*/ + uint16_t bString/*[]*/; /**< UNICODE encoded string */ +} ; +/** USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR USB_STRING_DESCRIPTOR; + +/** USB Common Descriptor */ +PRE_PACK struct POST_PACK _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; /**< Size of this descriptor in bytes*/ + uint8_t bDescriptorType; /**< Descriptor Type*/ +} ; +/** USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR; + +/** USB Other Speed Configuration */ +PRE_PACK struct POST_PACK _USB_OTHER_SPEED_CONFIGURATION +{ + uint8_t bLength; /**< Size of descriptor*/ + uint8_t bDescriptorType; /**< Other_speed_Configuration Type*/ + uint16_t wTotalLength; /**< Total length of data returned*/ + uint8_t bNumInterfaces; /**< Number of interfaces supported by this speed configuration*/ + uint8_t bConfigurationValue; /**< Value to use to select configuration*/ + uint8_t IConfiguration; /**< Index of string descriptor*/ + uint8_t bmAttributes; /**< Same as Configuration descriptor*/ + uint8_t bMaxPower; /**< Same as Configuration descriptor*/ +} ; +/** USB Other Speed Configuration */ +typedef struct _USB_OTHER_SPEED_CONFIGURATION USB_OTHER_SPEED_CONFIGURATION; + +/** \ingroup USBD_Core + * USB device stack/module handle. + */ +typedef void* USBD_HANDLE_T; + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) +#define B3VAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF),(((x) >> 16) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGURATION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_INTERFACE_ASSOC_DESC_SIZE (sizeof(USB_IAD_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) +#define USB_DEVICE_QUALI_SIZE (sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)) +#define USB_OTHER_SPEED_CONF_SIZE (sizeof(USB_OTHER_SPEED_CONFIGURATION)) + +/** @}*/ + +#endif /* __USBD_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_adc.h b/lpc_chip_15xx/inc/usbd/usbd_adc.h new file mode 100644 index 0000000..4b8e885 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_adc.h @@ -0,0 +1,377 @@ +/*********************************************************************** +* $Id:: mw_usbd_audio.h 165 2011-04-14 17:41:11Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Audio Device Class Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __AUDIO_H__ +#define __AUDIO_H__ + + +/* Audio Interface Subclass Codes */ +#define AUDIO_SUBCLASS_UNDEFINED 0x00 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_SUBCLASS_MIDISTREAMING 0x03 + +/* Audio Interface Protocol Codes */ +#define AUDIO_PROTOCOL_UNDEFINED 0x00 + + +/* Audio Descriptor Types */ +#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20 +#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21 +#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22 +#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23 +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + + +/* Audio Control Interface Descriptor Subtypes */ +#define AUDIO_CONTROL_UNDEFINED 0x00 +#define AUDIO_CONTROL_HEADER 0x01 +#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 +#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 +#define AUDIO_CONTROL_MIXER_UNIT 0x04 +#define AUDIO_CONTROL_SELECTOR_UNIT 0x05 +#define AUDIO_CONTROL_FEATURE_UNIT 0x06 +#define AUDIO_CONTROL_PROCESSING_UNIT 0x07 +#define AUDIO_CONTROL_EXTENSION_UNIT 0x08 + +/* Audio Streaming Interface Descriptor Subtypes */ +#define AUDIO_STREAMING_UNDEFINED 0x00 +#define AUDIO_STREAMING_GENERAL 0x01 +#define AUDIO_STREAMING_FORMAT_TYPE 0x02 +#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03 + +/* Audio Endpoint Descriptor Subtypes */ +#define AUDIO_ENDPOINT_UNDEFINED 0x00 +#define AUDIO_ENDPOINT_GENERAL 0x01 + + +/* Audio Descriptor Sizes */ +#define AUDIO_CONTROL_INTERFACE_DESC_SZ(n) 0x08+n +#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 +#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C +#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 +#define AUDIO_MIXER_UNIT_DESC_SZ(p,n) 0x0A+p+n +#define AUDIO_SELECTOR_UNIT_DESC_SZ(p) 0x06+p +#define AUDIO_FEATURE_UNIT_DESC_SZ(ch,n) 0x07+(ch+1)*n +#define AUDIO_PROCESSING_UNIT_DESC_SZ(p,n,x) 0x0D+p+n+x +#define AUDIO_EXTENSION_UNIT_DESC_SZ(p,n) 0x0D+p+n +#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 +#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 + + +/* Audio Processing Unit Process Types */ +#define AUDIO_UNDEFINED_PROCESS 0x00 +#define AUDIO_UP_DOWN_MIX_PROCESS 0x01 +#define AUDIO_DOLBY_PROLOGIC_PROCESS 0x02 +#define AUDIO_3D_STEREO_PROCESS 0x03 +#define AUDIO_REVERBERATION_PROCESS 0x04 +#define AUDIO_CHORUS_PROCESS 0x05 +#define AUDIO_DYN_RANGE_COMP_PROCESS 0x06 + + +/* Audio Request Codes */ +#define AUDIO_REQUEST_UNDEFINED 0x00 +#define AUDIO_REQUEST_SET_CUR 0x01 +#define AUDIO_REQUEST_GET_CUR 0x81 +#define AUDIO_REQUEST_SET_MIN 0x02 +#define AUDIO_REQUEST_GET_MIN 0x82 +#define AUDIO_REQUEST_SET_MAX 0x03 +#define AUDIO_REQUEST_GET_MAX 0x83 +#define AUDIO_REQUEST_SET_RES 0x04 +#define AUDIO_REQUEST_GET_RES 0x84 +#define AUDIO_REQUEST_SET_MEM 0x05 +#define AUDIO_REQUEST_GET_MEM 0x85 +#define AUDIO_REQUEST_GET_STAT 0xFF + + +/* Audio Control Selector Codes */ +#define AUDIO_CONTROL_UNDEFINED 0x00 /* Common Selector */ + +/* Terminal Control Selectors */ +#define AUDIO_COPY_PROTECT_CONTROL 0x01 + +/* Feature Unit Control Selectors */ +#define AUDIO_MUTE_CONTROL 0x01 +#define AUDIO_VOLUME_CONTROL 0x02 +#define AUDIO_BASS_CONTROL 0x03 +#define AUDIO_MID_CONTROL 0x04 +#define AUDIO_TREBLE_CONTROL 0x05 +#define AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06 +#define AUDIO_AUTOMATIC_GAIN_CONTROL 0x07 +#define AUDIO_DELAY_CONTROL 0x08 +#define AUDIO_BASS_BOOST_CONTROL 0x09 +#define AUDIO_LOUDNESS_CONTROL 0x0A + +/* Processing Unit Control Selectors: */ +#define AUDIO_ENABLE_CONTROL 0x01 /* Common Selector */ +#define AUDIO_MODE_SELECT_CONTROL 0x02 /* Common Selector */ + +/* - Up/Down-mix Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +/* AUDIO_MODE_SELECT_CONTROL 0x02 Common Selector */ + +/* - Dolby Prologic Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +/* AUDIO_MODE_SELECT_CONTROL 0x02 Common Selector */ + +/* - 3D Stereo Extender Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +#define AUDIO_SPACIOUSNESS_CONTROL 0x02 + +/* - Reverberation Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +#define AUDIO_REVERB_LEVEL_CONTROL 0x02 +#define AUDIO_REVERB_TIME_CONTROL 0x03 +#define AUDIO_REVERB_FEEDBACK_CONTROL 0x04 + +/* - Chorus Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +#define AUDIO_CHORUS_LEVEL_CONTROL 0x02 +#define AUDIO_SHORUS_RATE_CONTROL 0x03 +#define AUDIO_CHORUS_DEPTH_CONTROL 0x04 + +/* - Dynamic Range Compressor Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ +#define AUDIO_COMPRESSION_RATE_CONTROL 0x02 +#define AUDIO_MAX_AMPL_CONTROL 0x03 +#define AUDIO_THRESHOLD_CONTROL 0x04 +#define AUDIO_ATTACK_TIME_CONTROL 0x05 +#define AUDIO_RELEASE_TIME_CONTROL 0x06 + +/* Extension Unit Control Selectors */ +/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ + +/* Endpoint Control Selectors */ +#define AUDIO_SAMPLING_FREQ_CONTROL 0x01 +#define AUDIO_PITCH_CONTROL 0x02 + + +/* Audio Format Specific Control Selectors */ + +/* MPEG Control Selectors */ +#define AUDIO_MPEG_CONTROL_UNDEFINED 0x00 +#define AUDIO_MPEG_DUAL_CHANNEL_CONTROL 0x01 +#define AUDIO_MPEG_SECOND_STEREO_CONTROL 0x02 +#define AUDIO_MPEG_MULTILINGUAL_CONTROL 0x03 +#define AUDIO_MPEG_DYN_RANGE_CONTROL 0x04 +#define AUDIO_MPEG_SCALING_CONTROL 0x05 +#define AUDIO_MPEG_HILO_SCALING_CONTROL 0x06 + +/* AC-3 Control Selectors */ +#define AUDIO_AC3_CONTROL_UNDEFINED 0x00 +#define AUDIO_AC3_MODE_CONTROL 0x01 +#define AUDIO_AC3_DYN_RANGE_CONTROL 0x02 +#define AUDIO_AC3_SCALING_CONTROL 0x03 +#define AUDIO_AC3_HILO_SCALING_CONTROL 0x04 + + +/* Audio Format Types */ +#define AUDIO_FORMAT_TYPE_UNDEFINED 0x00 +#define AUDIO_FORMAT_TYPE_I 0x01 +#define AUDIO_FORMAT_TYPE_II 0x02 +#define AUDIO_FORMAT_TYPE_III 0x03 + + +/* Audio Format Type Descriptor Sizes */ +#define AUDIO_FORMAT_TYPE_I_DESC_SZ(n) 0x08+(n*3) +#define AUDIO_FORMAT_TYPE_II_DESC_SZ(n) 0x09+(n*3) +#define AUDIO_FORMAT_TYPE_III_DESC_SZ(n) 0x08+(n*3) +#define AUDIO_FORMAT_MPEG_DESC_SIZE 0x09 +#define AUDIO_FORMAT_AC3_DESC_SIZE 0x0A + + +/* Audio Data Format Codes */ + +/* Audio Data Format Type I Codes */ +#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000 +#define AUDIO_FORMAT_PCM 0x0001 +#define AUDIO_FORMAT_PCM8 0x0002 +#define AUDIO_FORMAT_IEEE_FLOAT 0x0003 +#define AUDIO_FORMAT_ALAW 0x0004 +#define AUDIO_FORMAT_MULAW 0x0005 + +/* Audio Data Format Type II Codes */ +#define AUDIO_FORMAT_TYPE_II_UNDEFINED 0x1000 +#define AUDIO_FORMAT_MPEG 0x1001 +#define AUDIO_FORMAT_AC3 0x1002 + +/* Audio Data Format Type III Codes */ +#define AUDIO_FORMAT_TYPE_III_UNDEFINED 0x2000 +#define AUDIO_FORMAT_IEC1937_AC3 0x2001 +#define AUDIO_FORMAT_IEC1937_MPEG1_L1 0x2002 +#define AUDIO_FORMAT_IEC1937_MPEG1_L2_3 0x2003 +#define AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003 +#define AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004 +#define AUDIO_FORMAT_IEC1937_MPEG2_L1_LS 0x2005 +#define AUDIO_FORMAT_IEC1937_MPEG2_L2_3 0x2006 + + +/* Predefined Audio Channel Configuration Bits */ +#define AUDIO_CHANNEL_M 0x0000 /* Mono */ +#define AUDIO_CHANNEL_L 0x0001 /* Left Front */ +#define AUDIO_CHANNEL_R 0x0002 /* Right Front */ +#define AUDIO_CHANNEL_C 0x0004 /* Center Front */ +#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */ +#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */ +#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */ +#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */ +#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */ +#define AUDIO_CHANNEL_S 0x0100 /* Surround */ +#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */ +#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */ +#define AUDIO_CHANNEL_T 0x0800 /* Top */ + + +/* Feature Unit Control Bits */ +#define AUDIO_CONTROL_MUTE 0x0001 +#define AUDIO_CONTROL_VOLUME 0x0002 +#define AUDIO_CONTROL_BASS 0x0004 +#define AUDIO_CONTROL_MID 0x0008 +#define AUDIO_CONTROL_TREBLE 0x0010 +#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020 +#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040 +#define AUDIO_CONTROL_DEALY 0x0080 +#define AUDIO_CONTROL_BASS_BOOST 0x0100 +#define AUDIO_CONTROL_LOUDNESS 0x0200 + +/* Processing Unit Control Bits: */ +#define AUDIO_CONTROL_ENABLE 0x0001 /* Common Bit */ +#define AUDIO_CONTROL_MODE_SELECT 0x0002 /* Common Bit */ + +/* - Up/Down-mix Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +/* AUDIO_CONTROL_MODE_SELECT 0x0002 Common Bit */ + +/* - Dolby Prologic Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +/* AUDIO_CONTROL_MODE_SELECT 0x0002 Common Bit */ + +/* - 3D Stereo Extender Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +#define AUDIO_CONTROL_SPACIOUSNESS 0x0002 + +/* - Reverberation Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +#define AUDIO_CONTROL_REVERB_TYPE 0x0002 +#define AUDIO_CONTROL_REVERB_LEVEL 0x0004 +#define AUDIO_CONTROL_REVERB_TIME 0x0008 +#define AUDIO_CONTROL_REVERB_FEEDBACK 0x0010 + +/* - Chorus Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +#define AUDIO_CONTROL_CHORUS_LEVEL 0x0002 +#define AUDIO_CONTROL_SHORUS_RATE 0x0004 +#define AUDIO_CONTROL_CHORUS_DEPTH 0x0008 + +/* - Dynamic Range Compressor Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ +#define AUDIO_CONTROL_COMPRESSION_RATE 0x0002 +#define AUDIO_CONTROL_MAX_AMPL 0x0004 +#define AUDIO_CONTROL_THRESHOLD 0x0008 +#define AUDIO_CONTROL_ATTACK_TIME 0x0010 +#define AUDIO_CONTROL_RELEASE_TIME 0x0020 + +/* Extension Unit Control Bits */ +/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ + +/* Endpoint Control Bits */ +#define AUDIO_CONTROL_SAMPLING_FREQ 0x01 +#define AUDIO_CONTROL_PITCH 0x02 +#define AUDIO_MAX_PACKETS_ONLY 0x80 + + +/* Audio Terminal Types */ + +/* USB Terminal Types */ +#define AUDIO_TERMINAL_USB_UNDEFINED 0x0100 +#define AUDIO_TERMINAL_USB_STREAMING 0x0101 +#define AUDIO_TERMINAL_USB_VENDOR_SPECIFIC 0x01FF + +/* Input Terminal Types */ +#define AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200 +#define AUDIO_TERMINAL_MICROPHONE 0x0201 +#define AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202 +#define AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203 +#define AUDIO_TERMINAL_OMNI_DIR_MICROPHONE 0x0204 +#define AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205 +#define AUDIO_TERMINAL_PROCESSING_MIC_ARRAY 0x0206 + +/* Output Terminal Types */ +#define AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300 +#define AUDIO_TERMINAL_SPEAKER 0x0301 +#define AUDIO_TERMINAL_HEADPHONES 0x0302 +#define AUDIO_TERMINAL_HEAD_MOUNTED_AUDIO 0x0303 +#define AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304 +#define AUDIO_TERMINAL_ROOM_SPEAKER 0x0305 +#define AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306 +#define AUDIO_TERMINAL_LOW_FREQ_SPEAKER 0x0307 + +/* Bi-directional Terminal Types */ +#define AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400 +#define AUDIO_TERMINAL_HANDSET 0x0401 +#define AUDIO_TERMINAL_HEAD_MOUNTED_HANDSET 0x0402 +#define AUDIO_TERMINAL_SPEAKERPHONE 0x0403 +#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOSUPRESS 0x0404 +#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOCANCEL 0x0405 + +/* Telephony Terminal Types */ +#define AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500 +#define AUDIO_TERMINAL_PHONE_LINE 0x0501 +#define AUDIO_TERMINAL_TELEPHONE 0x0502 +#define AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503 + +/* External Terminal Types */ +#define AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600 +#define AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601 +#define AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602 +#define AUDIO_TERMINAL_LINE_CONNECTOR 0x0603 +#define AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604 +#define AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605 +#define AUDIO_TERMINAL_1394_DA_STREAM 0x0606 +#define AUDIO_TERMINAL_1394_DA_STREAM_TRACK 0x0607 + +/* Embedded Function Terminal Types */ +#define AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700 +#define AUDIO_TERMINAL_CALIBRATION_NOISE 0x0701 +#define AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702 +#define AUDIO_TERMINAL_CD_PLAYER 0x0703 +#define AUDIO_TERMINAL_DAT 0x0704 +#define AUDIO_TERMINAL_DCC 0x0705 +#define AUDIO_TERMINAL_MINI_DISK 0x0706 +#define AUDIO_TERMINAL_ANALOG_TAPE 0x0707 +#define AUDIO_TERMINAL_PHONOGRAPH 0x0708 +#define AUDIO_TERMINAL_VCR_AUDIO 0x0709 +#define AUDIO_TERMINAL_VIDEO_DISC_AUDIO 0x070A +#define AUDIO_TERMINAL_DVD_AUDIO 0x070B +#define AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C +#define AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D +#define AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E +#define AUDIO_TERMINAL_DSS_AUDIO 0x070F +#define AUDIO_TERMINAL_RADIO_RECEIVER 0x0710 +#define AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711 +#define AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712 +#define AUDIO_TERMINAL_SYNTHESIZER 0x0713 + + +#endif /* __AUDIO_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_cdc.h b/lpc_chip_15xx/inc/usbd/usbd_cdc.h new file mode 100644 index 0000000..010e941 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_cdc.h @@ -0,0 +1,249 @@ +/*********************************************************************** +* $Id:: mw_usbd_cdc.h 165 2011-04-14 17:41:11Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Communication Device Class User module Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __CDC_H +#define __CDC_H + +#include "usbd.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. */ +PRE_PACK struct POST_PACK _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 */ +}; +typedef struct _CDC_HEADER_DESCRIPTOR CDC_HEADER_DESCRIPTOR; + +/* Call management functional descriptor */ +/* (usbcdc11.pdf, 5.2.3.2) */ +/* Describes the processing of calls for the communication class interface. */ +PRE_PACK struct POST_PACK _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) */ +}; +typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR 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. */ +PRE_PACK struct POST_PACK _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 */ +}; +typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR 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. */ +PRE_PACK struct POST_PACK _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 */ +}; +typedef struct _CDC_UNION_DESCRIPTOR CDC_UNION_DESCRIPTOR; + +/* Union functional descriptors with one slave interface */ +/* (usbcdc11.pdf, 5.2.3.8) */ +PRE_PACK struct POST_PACK _CDC_UNION_1SLAVE_DESCRIPTOR { + CDC_UNION_DESCRIPTOR sUnion; /* Union functional descriptor */ + uint8_t bSlaveInterfaces[1]; /* Slave interface 0 */ +}; +typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR CDC_UNION_1SLAVE_DESCRIPTOR; + +/* Line coding structure */ +/* Format of the data returned when a GetLineCoding request is received */ +/* (usbcdc11.pdf, 6.2.13) */ +PRE_PACK struct POST_PACK _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 */ +}; +typedef struct _CDC_LINE_CODING 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/lpc_chip_15xx/inc/usbd/usbd_cdcuser.h b/lpc_chip_15xx/inc/usbd/usbd_cdcuser.h new file mode 100644 index 0000000..92568e8 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_cdcuser.h @@ -0,0 +1,529 @@ +/*********************************************************************** +* $Id:: mw_usbd_cdcuser.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Communication Device Class User module Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __CDCUSER_H__ +#define __CDCUSER_H__ + +#include "error.h" +#include "usbd.h" +#include "usbd_cdc.h" + +/** \file + * \brief Communication Device Class (CDC) API structures and function prototypes. + * + * Definition of functions exported by ROM based CDC function driver. + * + */ + +/** \ingroup Group_USBD + * @defgroup USBD_CDC Communication Device Class (CDC) Function Driver + * \section Sec_CDCModDescription Module Description + * CDC Class Function Driver module. This module contains an internal implementation of the USB CDC Class. + * + * User applications can use this class driver instead of implementing the CDC-ACM class manually + * via the low-level USBD_HW and USBD_Core APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB CDC-ACM Class. + */ + +/*---------------------------------------------------------------------------- + We need a buffer for incoming data on USB port because USB receives + much faster than UART transmits + *---------------------------------------------------------------------------*/ +/* Buffer masks */ +#define CDC_BUF_SIZE (128) /* Output buffer in bytes (power 2) */ + /* large enough for file transfer */ +#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul) + +/** \brief Communication Device Class function driver initialization parameter data structure. + * \ingroup USBD_CDC + * + * \details This data structure is used to pass initialization parameters to the + * Communication Device Class function driver's init function. + * + */ +typedef struct USBD_CDC_INIT_PARAM +{ + /* memory allocation params */ + uint32_t mem_base; /**< Base memory location from where the stack can allocate + data and buffers. \note The memory address set in this field + should be accessible by USB DMA controller. Also this value + should be aligned on 4 byte boundary. + */ + uint32_t mem_size; /**< The size of memory buffer which stack can use. + \note The \em mem_size should be greater than the size + returned by USBD_CDC_API::GetMemSize() routine.*/ + /** Pointer to the control interface descriptor within the descriptor + * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T + * structure. The stack assumes both HS and FS use same BULK endpoints. + */ + uint8_t* cif_intf_desc; + /** Pointer to the data interface descriptor within the descriptor + * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T + * structure. The stack assumes both HS and FS use same BULK endpoints. + */ + uint8_t* dif_intf_desc; + + /* user defined functions */ + + /* required functions */ + /** + * Communication Interface Class specific get request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends CIC management element get requests. + * \note Applications implementing Abstract Control Model subclass can set this + * param to NULL. As the default driver parses ACM requests and calls the + * individual ACM call-back routines defined in this structure. For all other subclasses + * this routine should be provided by the application. + * \n + * The setup packet data (\em pSetup) is passed to the call-back so that application + * can extract the CIC request type and other associated data. By default the stack + * will assign \em pBuffer pointer to \em EP0Buff allocated at init. The application + * code can directly write data into this buffer as long as data is less than 64 byte. + * If more data has to be sent then application code should update \em pBuffer pointer + * and length accordingly. + * + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in, out] pBuffer Pointer to a pointer of data buffer containing request data. + * Pointer-to-pointer is used to implement zero-copy buffers. + * See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in, out] length Amount of data to be sent back to host. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CIC_GetRequest)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); + + /** + * Communication Interface Class specific set request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a CIC management element requests. + * \note Applications implementing Abstract Control Model subclass can set this + * param to NULL. As the default driver parses ACM requests and calls the + * individual ACM call-back routines defined in this structure. For all other subclasses + * this routine should be provided by the application. + * \n + * The setup packet data (\em pSetup) is passed to the call-back so that application can + * extract the CIC request type and other associated data. If a set request has data associated, + * then this call-back is called twice. + * -# First when setup request is received, at this time application code could update + * \em pBuffer pointer to point to the intended destination. The length param is set to 0 + * so that application code knows this is first time. By default the stack will + * assign \em pBuffer pointer to \em EP0Buff allocated at init. Note, if data length is + * greater than 64 bytes and application code doesn't update \em pBuffer pointer the + * stack will send STALL condition to host. + * -# Second when the data is received from the host. This time the length param is set + * with number of data bytes received. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in, out] pBuffer Pointer to a pointer of data buffer containing request data. + * Pointer-to-pointer is used to implement zero-copy buffers. + * See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in] length Amount of data copied to destination buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CIC_SetRequest)( USBD_HANDLE_T hCdc, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length); + + /** + * Communication Device Class specific BULK IN endpoint handler. + * + * The application software should provide the BULK IN endpoint handler. + * Applications should transfer data depending on the communication protocol type set in descriptors. + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CDC_BulkIN_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + + /** + * Communication Device Class specific BULK OUT endpoint handler. + * + * The application software should provide the BULK OUT endpoint handler. + * Applications should transfer data depending on the communication protocol type set in descriptors. + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CDC_BulkOUT_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + + /** + * Abstract control model(ACM) subclass specific SEND_ENCAPSULATED_COMMAND request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a SEND_ENCAPSULATED_COMMAND set request. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] buffer Pointer to the command buffer. + * \param[in] len Length of the command buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*SendEncpsCmd) (USBD_HANDLE_T hCDC, uint8_t* buffer, uint16_t len); + + /** + * Abstract control model(ACM) subclass specific GET_ENCAPSULATED_RESPONSE request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a GET_ENCAPSULATED_RESPONSE request. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in, out] buffer Pointer to a pointer of data buffer containing response data. + * Pointer-to-pointer is used to implement zero-copy buffers. + * See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in, out] len Amount of data to be sent back to host. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*GetEncpsResp) (USBD_HANDLE_T hCDC, uint8_t** buffer, uint16_t* len); + + /** + * Abstract control model(ACM) subclass specific SET_COMM_FEATURE request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a SET_COMM_FEATURE set request. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] feature Communication feature type. See usbcdc11.pdf, section 6.2.4, Table 47. + * \param[in] buffer Pointer to the settings buffer for the specified communication feature. + * \param[in] len Length of the request buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*SetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t* buffer, uint16_t len); + + /** + * Abstract control model(ACM) subclass specific GET_COMM_FEATURE request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a GET_ENCAPSULATED_RESPONSE request. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] feature Communication feature type. See usbcdc11.pdf, section 6.2.4, Table 47. + * \param[in, out] buffer Pointer to a pointer of data buffer containing current settings + * for the communication feature. + * Pointer-to-pointer is used to implement zero-copy buffers. + * \param[in, out] len Amount of data to be sent back to host. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*GetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t** pBuffer, uint16_t* len); + + /** + * Abstract control model(ACM) subclass specific CLEAR_COMM_FEATURE request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a CLEAR_COMM_FEATURE request. In the call-back the application + * should Clears the settings for a particular communication feature. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] feature Communication feature type. See usbcdc11.pdf, section 6.2.4, Table 47. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*ClrCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature); + + /** + * Abstract control model(ACM) subclass specific SET_CONTROL_LINE_STATE request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a SET_CONTROL_LINE_STATE request. RS-232 signal used to tell the DCE + * device the DTE device is now present + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] state The state value uses bitmap values defined in usbcdc11.pdf, + * section 6.2.14, Table 51. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*SetCtrlLineState) (USBD_HANDLE_T hCDC, uint16_t state); + + /** + * Abstract control model(ACM) subclass specific SEND_BREAK request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a SEND_BREAK request. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] mstime Duration of Break signal in milliseconds. If mstime is FFFFh, then + * the application should send break until another SendBreak request is received + * with the wValue of 0000h. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*SendBreak) (USBD_HANDLE_T hCDC, uint16_t mstime); + + /** + * Abstract control model(ACM) subclass specific SET_LINE_CODING request call-back function. + * + * This function is provided by the application software. This function gets called + * when host sends a SET_LINE_CODING request. The application should configure the device + * per DTE rate, stop-bits, parity, and number-of-character bits settings provided in + * command buffer. See usbcdc11.pdf, section 6.2.13, table 50 for detail of the command buffer. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] line_coding Pointer to the CDC_LINE_CODING command buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*SetLineCode) (USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding); + + /** + * Optional Communication Device Class specific INTERRUPT IN endpoint handler. + * + * The application software should provide the INT IN endpoint handler. + * Applications should transfer data depending on the communication protocol type set in descriptors. + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CDC_InterruptEP_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + + /** + * Optional user override-able function to replace the default CDC class handler. + * + * The application software could override the default EP0 class handler with their + * own by providing the handler function address as this data member of the parameter + * structure. Application which like the default handler should set this data member + * to zero before calling the USBD_CDC_API::Init(). + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*CDC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + +} USBD_CDC_INIT_PARAM_T; + +/** \brief CDC class API functions structure. + * \ingroup USBD_CDC + * + * This module exposes functions which interact directly with USB device controller hardware. + * + */ +typedef struct USBD_CDC_API +{ + /** \fn uint32_t GetMemSize(USBD_CDC_INIT_PARAM_T* param) + * Function to determine the memory required by the CDC function driver module. + * + * This function is called by application layer before calling pUsbApi->CDC->Init(), to allocate memory used + * by CDC function driver module. The application should allocate the memory which is accessible by USB + * controller/DMA controller. + * \note Some memory areas are not accessible by all bus masters. + * + * \param[in] param Structure containing CDC function driver module initialization parameters. + * \return Returns the required memory size in bytes. + */ + uint32_t (*GetMemSize)(USBD_CDC_INIT_PARAM_T* param); + + /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param) + * Function to initialize CDC function driver module. + * + * This function is called by application layer to initialize CDC function driver module. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in, out] param Structure containing CDC function driver module initialization parameters. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_BAD_MEM_BUF Memory buffer passed is not 4-byte + * aligned or smaller than required. + * \retval ERR_API_INVALID_PARAM2 Either CDC_Write() or CDC_Read() or + * CDC_Verify() callbacks are not defined. + * \retval ERR_USBD_BAD_INTF_DESC Wrong interface descriptor is passed. + * \retval ERR_USBD_BAD_EP_DESC Wrong endpoint descriptor is passed. + */ + ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param, USBD_HANDLE_T* phCDC); + + /** \fn ErrorCode_t SendNotification(USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data) + * Function to send CDC class notifications to host. + * + * This function is called by application layer to send CDC class notifications to host. + * See usbcdc11.pdf, section 6.3, Table 67 for various notification types the CDC device can send. + * \note The current version of the driver only supports following notifications allowed by ACM subclass: + * CDC_NOTIFICATION_NETWORK_CONNECTION, CDC_RESPONSE_AVAILABLE, CDC_NOTIFICATION_SERIAL_STATE. + * \n + * For all other notifications application should construct the notification buffer appropriately + * and call hw->USB_WriteEP() for interrupt endpoint associated with the interface. + * + * \param[in] hCdc Handle to CDC function driver. + * \param[in] bNotification Notification type allowed by ACM subclass. Should be CDC_NOTIFICATION_NETWORK_CONNECTION, + * CDC_RESPONSE_AVAILABLE or CDC_NOTIFICATION_SERIAL_STATE. For all other types ERR_API_INVALID_PARAM2 + * is returned. See usbcdc11.pdf, section 3.6.2.1, table 5. + * \param[in] data Data associated with notification. + * \n For CDC_NOTIFICATION_NETWORK_CONNECTION a non-zero data value is interpreted as connected state. + * \n For CDC_RESPONSE_AVAILABLE this parameter is ignored. + * \n For CDC_NOTIFICATION_SERIAL_STATE the data should use bitmap values defined in usbcdc11.pdf, + * section 6.3.5, Table 69. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_API_INVALID_PARAM2 If unsupported notification type is passed. + * + */ + ErrorCode_t (*SendNotification)(USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data); + +} USBD_CDC_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes + *-----------------------------------------------------------------------------*/ +/** @cond ADVANCED_API */ + +typedef struct _CDC_CTRL_T +{ + USB_CORE_CTRL_T* pUsbCtrl; + /* notification buffer */ + uint8_t notice_buf[12]; + CDC_LINE_CODING line_coding; + uint8_t pad0; + + uint8_t cif_num; /* control interface number */ + uint8_t dif_num; /* data interface number */ + uint8_t epin_num; /* BULK IN endpoint number */ + uint8_t epout_num; /* BULK OUT endpoint number */ + uint8_t epint_num; /* Interrupt IN endpoint number */ + uint8_t pad[3]; + /* user defined functions */ + ErrorCode_t (*SendEncpsCmd) (USBD_HANDLE_T hCDC, uint8_t* buffer, uint16_t len); + ErrorCode_t (*GetEncpsResp) (USBD_HANDLE_T hCDC, uint8_t** buffer, uint16_t* len); + ErrorCode_t (*SetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t* buffer, uint16_t len); + ErrorCode_t (*GetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t** pBuffer, uint16_t* len); + ErrorCode_t (*ClrCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature); + ErrorCode_t (*SetCtrlLineState) (USBD_HANDLE_T hCDC, uint16_t state); + ErrorCode_t (*SendBreak) (USBD_HANDLE_T hCDC, uint16_t state); + ErrorCode_t (*SetLineCode) (USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding); + + /* virtual functions */ + ErrorCode_t (*CIC_GetRequest)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); + ErrorCode_t (*CIC_SetRequest)( USBD_HANDLE_T hCdc, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length); + +} USB_CDC_CTRL_T; + +/* structure used by old ROM drivers, needed for workaround */ +typedef struct _CDC0_CTRL_T { + USB_CORE_CTRL_T *pUsbCtrl; + /* notification buffer */ + uint8_t notice_buf[12]; + CDC_LINE_CODING line_coding; + + uint8_t cif_num; /* control interface number */ + uint8_t dif_num; /* data interface number */ + uint8_t epin_num; /* BULK IN endpoint number */ + uint8_t epout_num; /* BULK OUT endpoint number */ + uint8_t epint_num; /* Interrupt IN endpoint number */ + /* user defined functions */ + ErrorCode_t (*SendEncpsCmd)(USBD_HANDLE_T hCDC, uint8_t *buffer, uint16_t len); + ErrorCode_t (*GetEncpsResp)(USBD_HANDLE_T hCDC, uint8_t * *buffer, uint16_t *len); + ErrorCode_t (*SetCommFeature)(USBD_HANDLE_T hCDC, uint16_t feature, uint8_t *buffer, uint16_t len); + ErrorCode_t (*GetCommFeature)(USBD_HANDLE_T hCDC, uint16_t feature, uint8_t * *pBuffer, uint16_t *len); + ErrorCode_t (*ClrCommFeature)(USBD_HANDLE_T hCDC, uint16_t feature); + ErrorCode_t (*SetCtrlLineState)(USBD_HANDLE_T hCDC, uint16_t state); + ErrorCode_t (*SendBreak)(USBD_HANDLE_T hCDC, uint16_t state); + ErrorCode_t (*SetLineCode)(USBD_HANDLE_T hCDC, CDC_LINE_CODING *line_coding); + + /* virtual functions */ + ErrorCode_t (*CIC_GetRequest)(USBD_HANDLE_T hHid, USB_SETUP_PACKET *pSetup, uint8_t * *pBuffer, uint16_t *length); + ErrorCode_t (*CIC_SetRequest)(USBD_HANDLE_T hCdc, USB_SETUP_PACKET *pSetup, uint8_t * *pBuffer, uint16_t length); + +} USB_CDC0_CTRL_T; + +typedef ErrorCode_t (*CIC_SetRequest_t)(USBD_HANDLE_T hCdc, USB_SETUP_PACKET *pSetup, uint8_t * *pBuffer, uint16_t length); + +/** @cond DIRECT_API */ +extern uint32_t mwCDC_GetMemSize(USBD_CDC_INIT_PARAM_T* param); +extern ErrorCode_t mwCDC_init(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param, USBD_HANDLE_T* phCDC); +extern ErrorCode_t mwCDC_SendNotification (USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data); +/** @endcond */ + +/** @endcond */ + + + + + +#endif /* __CDCUSER_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_core.h b/lpc_chip_15xx/inc/usbd/usbd_core.h new file mode 100644 index 0000000..5ff60ff --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_core.h @@ -0,0 +1,585 @@ +/*********************************************************************** +* $Id:: mw_usbd_core.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB core controller structure definitions and function prototypes. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __MW_USBD_CORE_H__ +#define __MW_USBD_CORE_H__ + +#include "error.h" +#include "usbd.h" +#include "app_usbd_cfg.h" + +/** \file + * \brief ROM API for USB device stack. + * + * Definition of functions exported by core layer of ROM based USB device stack. + * + */ + +/** \ingroup Group_USBD + * @defgroup USBD_Core USB Core Layer + * \section Sec_CoreModDescription Module Description + * The USB Core Layer implements the device abstraction defined in the Universal Serial Bus Specification, + * for applications to interact with the USB device interface on the device. The software in this layer responds to + * standard requests and returns standard descriptors. In current stack the Init() routine part of + * \ref USBD_HW_API_T structure initializes both hardware layer and core layer. + */ + + +/* function pointer types */ + +/** \ingroup USBD_Core + * \typedef USB_CB_T + * \brief USB device stack's event callback function type. + * + * The USB device stack exposes several event triggers through callback to application layer. The + * application layer can register methods to be called when such USB event happens. + * + * \param[in] hUsb Handle to the USB device stack. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx Other error conditions. + * + */ +typedef ErrorCode_t (*USB_CB_T) (USBD_HANDLE_T hUsb); + +/** \ingroup USBD_Core + * \typedef USB_PARAM_CB_T + * \brief USB device stack's event callback function type. + * + * The USB device stack exposes several event triggers through callback to application layer. The + * application layer can register methods to be called when such USB event happens. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] param1 Extra information related to the event. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ +typedef ErrorCode_t (*USB_PARAM_CB_T) (USBD_HANDLE_T hUsb, uint32_t param1); + +/** \ingroup USBD_Core + * \typedef USB_EP_HANDLER_T + * \brief USBD setup request and endpoint event handler type. + * + * The application layer should define the custom class's EP0 handler with function signature. + * The stack calls all the registered class handlers on any EP0 event before going through default + * handling of the event. This gives the class handlers to implement class specific request handlers + * and also to override the default stack handling for a particular event targeted to the interface. + * If an event is not handled by the callback the function should return ERR_USBD_UNHANDLED. For all + * other return codes the stack assumes that callback has taken care of the event and hence will not + * process the event any further and issues a STALL condition on EP0 indicating error to the host. + * \n + * For endpoint interrupt handler the return value is ignored by the stack. + * \n + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ +typedef ErrorCode_t (*USB_EP_HANDLER_T)(USBD_HANDLE_T hUsb, void* data, uint32_t event); + + +/** \ingroup USBD_Core + * \brief USB descriptors data structure. + * \ingroup USBD_Core + * + * \details This structure is used as part of USB device stack initialization + * parameter structure \ref USBD_API_INIT_PARAM_T. This structure contains + * pointers to various descriptor arrays needed by the stack. These descriptors + * are reported to USB host as part of enumerations process. + * + * \note All descriptor pointers assigned in this structure should be on 4 byte + * aligned address boundary. + */ +typedef struct _USB_CORE_DESCS_T +{ + uint8_t *device_desc; /**< Pointer to USB device descriptor */ + uint8_t *string_desc; /**< Pointer to array of USB string descriptors */ + uint8_t *full_speed_desc; /**< Pointer to USB device configuration descriptor + * when device is operating in full speed mode. + */ + uint8_t *high_speed_desc; /**< Pointer to USB device configuration descriptor + * when device is operating in high speed mode. For + * full-speed only implementation this pointer should + * be same as full_speed_desc. + */ + uint8_t *device_qualifier; /**< Pointer to USB device qualifier descriptor. For + * full-speed only implementation this pointer should + * be set to null (0). + */ +} USB_CORE_DESCS_T; + +/** \brief USB device stack initialization parameter data structure. + * \ingroup USBD_Core + * + * \details This data structure is used to pass initialization parameters to the + * USB device stack's init function. + * + */ +typedef struct USBD_API_INIT_PARAM +{ + uint32_t usb_reg_base; /**< USB device controller's base register address. */ + uint32_t mem_base; /**< Base memory location from where the stack can allocate + data and buffers. \note The memory address set in this field + should be accessible by USB DMA controller. Also this value + should be aligned on 2048 byte boundary. + */ + uint32_t mem_size; /**< The size of memory buffer which stack can use. + \note The \em mem_size should be greater than the size + returned by USBD_HW_API::GetMemSize() routine.*/ + uint8_t max_num_ep; /**< max number of endpoints supported by the USB device + controller instance (specified by \em usb_reg_base field) + to which this instance of stack is attached. + */ + uint8_t pad0[3]; + /* USB Device Events Callback Functions */ + /** Event for USB interface reset. This event fires when the USB host requests that the device + * reset its interface. This event fires after the control endpoint has been automatically + * configured by the library. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will prevent the device from enumerating correctly or operate properly. + * + */ + USB_CB_T USB_Reset_Event; + + /** Event for USB suspend. This event fires when the USB host suspends the device by halting its + * transmission of Start Of Frame pulses to the device. This is generally hooked in order to move + * the device over to a low power state until the host wakes up the device. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will cause other system issues. + */ + USB_CB_T USB_Suspend_Event; + + /** Event for USB wake up or resume. This event fires when a the USB device interface is suspended + * and the host wakes up the device by supplying Start Of Frame pulses. This is generally + * hooked to pull the user application out of a low power state and back into normal operating + * mode. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will cause other system issues. + * + */ + USB_CB_T USB_Resume_Event; + + /** Reserved parameter should be set to zero. */ + USB_CB_T reserved_sbz; + + /** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB + * frame, once per millisecond in full-speed mode or once per 125 microseconds in high-speed mode, + * and is synchronized to the USB bus. + * + * This event is time-critical; it is run once per millisecond (full-speed mode) and thus long handlers + * will significantly degrade device performance. This event should only be enabled when needed to + * reduce device wake-ups. + * + * \note This event is not normally active - it must be manually enabled and disabled via the USB interrupt + * register. + * \n\n + */ + USB_CB_T USB_SOF_Event; + + /** Event for remote wake-up configuration, when enabled. This event fires when the USB host + * request the device to configure itself for remote wake-up capability. The USB host sends + * this request to device which report remote wake-up capable in their device descriptors, + * before going to low-power state. The application layer should implement this callback if + * they have any special on board circuit to trigger remote wake up event. Also application + * can use this callback to differentiate the following SUSPEND event is caused by cable plug-out + * or host SUSPEND request. The device can wake-up host only after receiving this callback and + * remote wake-up feature is enabled by host. To signal remote wake-up the device has to generate + * resume signaling on bus by calling usapi.hw->WakeUp() routine. + * + * \n\n + * \param[in] hUsb Handle to the USB device stack. + * \param[in] param1 When 0 - Clear the wake-up configuration, 1 - Enable the wake-up configuration. + * \return The call back should return \ref ErrorCode_t type to indicate success or error condition. + */ + USB_PARAM_CB_T USB_WakeUpCfg; + + /** Reserved parameter should be set to zero. */ + USB_PARAM_CB_T USB_Power_Event; + + /** Event for error condition. This event fires when USB device controller detect + * an error condition in the system. + * + * \n\n + * \param[in] hUsb Handle to the USB device stack. + * \param[in] param1 USB device interrupt status register. + * \return The call back should return \ref ErrorCode_t type to indicate success or error condition. + */ + USB_PARAM_CB_T USB_Error_Event; + + /* USB Core Events Callback Functions */ + /** Event for USB configuration number changed. This event fires when a the USB host changes the + * selected configuration number. On receiving configuration change request from host, the stack + * enables/configures the endpoints needed by the new configuration before calling this callback + * function. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will prevent the device from enumerating correctly or operate properly. + * + */ + USB_CB_T USB_Configure_Event; + + /** Event for USB interface setting changed. This event fires when a the USB host changes the + * interface setting to one of alternate interface settings. On receiving interface change + * request from host, the stack enables/configures the endpoints needed by the new alternate + * interface setting before calling this callback function. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will prevent the device from enumerating correctly or operate properly. + * + */ + USB_CB_T USB_Interface_Event; + + /** Event for USB feature changed. This event fires when a the USB host send set/clear feature + * request. The stack handles this request for USB_FEATURE_REMOTE_WAKEUP, USB_FEATURE_TEST_MODE + * and USB_FEATURE_ENDPOINT_STALL features only. On receiving feature request from host, the + * stack handle the request appropriately and then calls this callback function. + * \n + * \note This event is called from USB_ISR context and hence is time-critical. Having delays in this + * callback will prevent the device from enumerating correctly or operate properly. + * + */ + USB_CB_T USB_Feature_Event; + + /* cache and MMU translation functions */ + /** Reserved parameter for future use. should be set to zero. */ + uint32_t (* virt_to_phys)(void* vaddr); + /** Reserved parameter for future use. should be set to zero. */ + void (* cache_flush)(uint32_t* start_adr, uint32_t* end_adr); + +} USBD_API_INIT_PARAM_T; + + +/** \brief USBD stack Core API functions structure. + * \ingroup USBD_Core + * + * \details This module exposes functions which interact directly with USB device stack's core layer. + * The application layer uses this component when it has to implement custom class function driver or + * standard class function driver which is not part of the current USB device stack. + * The functions exposed by this interface are to register class specific EP0 handlers and corresponding + * utility functions to manipulate EP0 state machine of the stack. This interface also exposes + * function to register custom endpoint interrupt handler. + * + */ +typedef struct USBD_CORE_API +{ + /** \fn ErrorCode_t RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data) + * Function to register class specific EP0 event handler with USB device stack. + * + * The application layer uses this function when it has to register the custom class's EP0 handler. + * The stack calls all the registered class handlers on any EP0 event before going through default + * handling of the event. This gives the class handlers to implement class specific request handlers + * and also to override the default stack handling for a particular event targeted to the interface. + * Check \ref USB_EP_HANDLER_T for more details on how the callback function should be implemented. Also + * application layer could use this function to register EP0 handler which responds to vendor specific + * requests. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] pfn Class specific EP0 handler function. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_TOO_MANY_CLASS_HDLR(0x0004000c) The number of class handlers registered is + greater than the number of handlers allowed by the stack. + * + */ + ErrorCode_t (*RegisterClassHandler)(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data); + + /** \fn ErrorCode_t RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data) + * Function to register interrupt/event handler for the requested endpoint with USB device stack. + * + * The application layer uses this function to register the endpoint event handler. + * The stack calls all the registered endpoint handlers when + * - USB_EVT_OUT or USB_EVT_OUT_NAK events happen for OUT endpoint. + * - USB_EVT_IN or USB_EVT_IN_NAK events happen for IN endpoint. + * Check USB_EP_HANDLER_T for more details on how the callback function should be implemented. + * \note By default endpoint _NAK events are not enabled. Application should call \ref USBD_HW_API_T::EnableEvent + * for the corresponding endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] ep_index Endpoint index. Computed as + * - For OUT endpoints = 2 * endpoint number eg. for EP2_OUT it is 4. + * - For IN endopoints = (2 * endpoint number) + 1 eg. for EP2_IN it is 5. + * \param[in] pfn Endpoint event handler function. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_API_INVALID_PARAM2 ep_index is outside the boundary ( < 2 * USBD_API_INIT_PARAM_T::max_num_ep). + * + */ + ErrorCode_t (*RegisterEpHandler)(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data); + + /** \fn void SetupStage(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in setup state. + * + * This function is called by USB stack and the application layer to + * set the EP0 state machine in setup state. This function will read + * the setup packet received from USB host into stack's buffer. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*SetupStage )(USBD_HANDLE_T hUsb); + + /** \fn void DataInStage(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in data_in state. + * + * This function is called by USB stack and the application layer to + * set the EP0 state machine in data_in state. This function will write + * the data present in EP0Data buffer to EP0 FIFO for transmission to host. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*DataInStage)(USBD_HANDLE_T hUsb); + + /** \fn void DataOutStage(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in data_out state. + * + * This function is called by USB stack and the application layer to + * set the EP0 state machine in data_out state. This function will read + * the control data (EP0 out packets) received from USB host into EP0Data buffer. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*DataOutStage)(USBD_HANDLE_T hUsb); + + /** \fn void StatusInStage(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in status_in state. + * + * This function is called by USB stack and the application layer to + * set the EP0 state machine in status_in state. This function will send + * zero length IN packet on EP0 to host, indicating positive status. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*StatusInStage)(USBD_HANDLE_T hUsb); + /** \fn void StatusOutStage(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in status_out state. + * + * This function is called by USB stack and the application layer to + * set the EP0 state machine in status_out state. This function will read + * the zero length OUT packet received from USB host on EP0. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*StatusOutStage)(USBD_HANDLE_T hUsb); + + /** \fn void StallEp0(USBD_HANDLE_T hUsb) + * Function to set EP0 state machine in stall state. + * + * This function is called by USB stack and the application layer to + * generate STALL signaling on EP0 endpoint. This function will also + * reset the EP0Data buffer. + * \n + * \note This interface is provided to users to invoke this function in other + * scenarios which are not handle by current stack. In most user applications + * this function is not called directly.Also this function can be used by + * users who are selectively modifying the USB device stack's standard handlers + * through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*StallEp0)(USBD_HANDLE_T hUsb); + +} USBD_CORE_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes + *-----------------------------------------------------------------------------*/ + + /** @cond ADVANCED_API */ + +/* forward declaration */ +struct _USB_CORE_CTRL_T; +typedef struct _USB_CORE_CTRL_T USB_CORE_CTRL_T; + +/* USB device Speed status defines */ +#define USB_FULL_SPEED 0 +#define USB_HIGH_SPEED 1 + +/* USB Endpoint Data Structure */ +typedef struct _USB_EP_DATA +{ + uint8_t *pData; + uint16_t Count; + uint16_t pad0; +} USB_EP_DATA; + + +/* USB core controller data structure */ +struct _USB_CORE_CTRL_T +{ + /* override-able function pointers ~ c++ style virtual functions*/ + USB_CB_T USB_EvtSetupHandler; + USB_CB_T USB_EvtOutHandler; + USB_PARAM_CB_T USB_ReqVendor; + USB_CB_T USB_ReqGetStatus; + USB_CB_T USB_ReqGetDescriptor; + USB_CB_T USB_ReqGetConfiguration; + USB_CB_T USB_ReqSetConfiguration; + USB_CB_T USB_ReqGetInterface; + USB_CB_T USB_ReqSetInterface; + USB_PARAM_CB_T USB_ReqSetClrFeature; + + /* USB Device Events Callback Functions */ + USB_CB_T USB_Reset_Event; + USB_CB_T USB_Suspend_Event; + USB_CB_T USB_Resume_Event; + USB_CB_T USB_SOF_Event; + USB_PARAM_CB_T USB_Power_Event; + USB_PARAM_CB_T USB_Error_Event; + USB_PARAM_CB_T USB_WakeUpCfg; + + /* USB Core Events Callback Functions */ + USB_CB_T USB_Configure_Event; + USB_CB_T USB_Interface_Event; + USB_CB_T USB_Feature_Event; + + /* cache and MMU translation functions */ + uint32_t (* virt_to_phys)(void* vaddr); + void (* cache_flush)(uint32_t* start_adr, uint32_t* end_adr); + + /* event handlers for endpoints. */ + USB_EP_HANDLER_T ep_event_hdlr[2 * USB_MAX_EP_NUM]; + void* ep_hdlr_data[2 * USB_MAX_EP_NUM]; + + /* USB class handlers */ + USB_EP_HANDLER_T ep0_hdlr_cb[USB_MAX_IF_NUM]; + void* ep0_cb_data[USB_MAX_IF_NUM]; + uint8_t num_ep0_hdlrs; + /* USB Core data Variables */ + uint8_t max_num_ep; /* max number of endpoints supported by the HW */ + uint8_t device_speed; + uint8_t num_interfaces; + uint8_t device_addr; + uint8_t config_value; + uint16_t device_status; + uint8_t *device_desc; + uint8_t *string_desc; + uint8_t *full_speed_desc; + uint8_t *high_speed_desc; + uint8_t *device_qualifier; + uint32_t ep_mask; + uint32_t ep_halt; + uint32_t ep_stall; + uint8_t alt_setting[USB_MAX_IF_NUM]; + /* HW driver data pointer */ + void* hw_data; + + /* USB Endpoint 0 Data Info */ + USB_EP_DATA EP0Data; + + /* USB Endpoint 0 Buffer */ + //ALIGNED(4) + uint8_t EP0Buf[64]; + + /* USB Setup Packet */ + //ALIGNED(4) + USB_SETUP_PACKET SetupPacket; + +}; + +/* USB Core Functions */ +extern void mwUSB_InitCore(USB_CORE_CTRL_T* pCtrl, USB_CORE_DESCS_T* pdescr, USBD_API_INIT_PARAM_T* param); +extern void mwUSB_ResetCore(USBD_HANDLE_T hUsb); + +/* inline functions */ +static INLINE void USB_SetSpeedMode(USB_CORE_CTRL_T* pCtrl, uint8_t mode) +{ + pCtrl->device_speed = mode; +} + +static INLINE bool USB_IsConfigured(USBD_HANDLE_T hUsb) +{ + USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*) hUsb; + return (bool) (pCtrl->config_value != 0); +} + +/** @cond DIRECT_API */ +/* midleware API */ +extern ErrorCode_t mwUSB_RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data); +extern ErrorCode_t mwUSB_RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data); +extern void mwUSB_SetupStage (USBD_HANDLE_T hUsb); +extern void mwUSB_DataInStage(USBD_HANDLE_T hUsb); +extern void mwUSB_DataOutStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StatusInStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StatusOutStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StallEp0(USBD_HANDLE_T hUsb); +extern ErrorCode_t mwUSB_RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data); +extern ErrorCode_t mwUSB_RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data); +extern void mwUSB_SetupStage (USBD_HANDLE_T hUsb); +extern void mwUSB_DataInStage(USBD_HANDLE_T hUsb); +extern void mwUSB_DataOutStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StatusInStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StatusOutStage(USBD_HANDLE_T hUsb); +extern void mwUSB_StallEp0(USBD_HANDLE_T hUsb); +/** @endcond */ + +/** @endcond */ + +#endif /* __MW_USBD_CORE_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_desc.h b/lpc_chip_15xx/inc/usbd/usbd_desc.h new file mode 100644 index 0000000..c03f942 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_desc.h @@ -0,0 +1,48 @@ +/*********************************************************************** +* $Id:: mw_usbd_desc.h 165 2011-04-14 17:41:11Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Descriptors Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef __USBDESC_H__ +#define __USBDESC_H__ + +#include "usbd.h" + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) +#define B3VAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF),(((x) >> 16) & 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 USB_DEVICE_QUALI_SIZE (sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)) +#define USB_OTHER_SPEED_CONF_SIZE (sizeof(USB_OTHER_SPEED_CONFIGURATION)) + +//#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR)) +//#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor)) + +extern const uint8_t HID_ReportDescriptor[]; +extern const uint16_t HID_ReportDescSize; +extern const uint16_t HID_DescOffset; + + +#endif /* __USBDESC_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_dfu.h b/lpc_chip_15xx/inc/usbd/usbd_dfu.h new file mode 100644 index 0000000..52134eb --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_dfu.h @@ -0,0 +1,120 @@ +/*********************************************************************** +* $Id:: mw_usbd_dfu.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* Device Firmware Upgrade (DFU) module. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __MW_USBD_DFU_H__ +#define __MW_USBD_DFU_H__ + +#include "usbd.h" + +/** \file + * \brief Device Firmware Upgrade (DFU) class descriptors. + * + * Definition of DFU class descriptors and their bit defines. + * + */ + +/** + * If USB device is only DFU capable, DFU Interface number is always 0. + * if USB device is (DFU + Other Class (Audio/Mass Storage/HID), DFU + * Interface number should also be 0 in this implementation. + */ +#define USB_DFU_IF_NUM 0x0 + +#define USB_DFU_DESCRIPTOR_TYPE 0x21 +#define USB_DFU_DESCRIPTOR_SIZE 9 +#define USB_DFU_SUBCLASS 0x01 + +/* DFU class-specific requests (Section 3, DFU Rev 1.1) */ +#define USB_REQ_DFU_DETACH 0x00 +#define USB_REQ_DFU_DNLOAD 0x01 +#define USB_REQ_DFU_UPLOAD 0x02 +#define USB_REQ_DFU_GETSTATUS 0x03 +#define USB_REQ_DFU_CLRSTATUS 0x04 +#define USB_REQ_DFU_GETSTATE 0x05 +#define USB_REQ_DFU_ABORT 0x06 + +#define DFU_STATUS_OK 0x00 +#define DFU_STATUS_errTARGET 0x01 +#define DFU_STATUS_errFILE 0x02 +#define DFU_STATUS_errWRITE 0x03 +#define DFU_STATUS_errERASE 0x04 +#define DFU_STATUS_errCHECK_ERASED 0x05 +#define DFU_STATUS_errPROG 0x06 +#define DFU_STATUS_errVERIFY 0x07 +#define DFU_STATUS_errADDRESS 0x08 +#define DFU_STATUS_errNOTDONE 0x09 +#define DFU_STATUS_errFIRMWARE 0x0a +#define DFU_STATUS_errVENDOR 0x0b +#define DFU_STATUS_errUSBR 0x0c +#define DFU_STATUS_errPOR 0x0d +#define DFU_STATUS_errUNKNOWN 0x0e +#define DFU_STATUS_errSTALLEDPKT 0x0f + +enum dfu_state { + DFU_STATE_appIDLE = 0, + DFU_STATE_appDETACH = 1, + DFU_STATE_dfuIDLE = 2, + DFU_STATE_dfuDNLOAD_SYNC = 3, + DFU_STATE_dfuDNBUSY = 4, + DFU_STATE_dfuDNLOAD_IDLE = 5, + DFU_STATE_dfuMANIFEST_SYNC = 6, + DFU_STATE_dfuMANIFEST = 7, + DFU_STATE_dfuMANIFEST_WAIT_RST= 8, + DFU_STATE_dfuUPLOAD_IDLE = 9, + DFU_STATE_dfuERROR = 10 +}; + +#define DFU_EP0_NONE 0 +#define DFU_EP0_UNHANDLED 1 +#define DFU_EP0_STALL 2 +#define DFU_EP0_ZLP 3 +#define DFU_EP0_DATA 4 + +#define USB_DFU_CAN_DOWNLOAD (1 << 0) +#define USB_DFU_CAN_UPLOAD (1 << 1) +#define USB_DFU_MANIFEST_TOL (1 << 2) +#define USB_DFU_WILL_DETACH (1 << 3) + +PRE_PACK struct POST_PACK _USB_DFU_FUNC_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wDetachTimeOut; + uint16_t wTransferSize; + uint16_t bcdDFUVersion; +}; +typedef struct _USB_DFU_FUNC_DESCRIPTOR USB_DFU_FUNC_DESCRIPTOR; + +PRE_PACK struct POST_PACK _DFU_STATUS { + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +}; +typedef struct _DFU_STATUS DFU_STATUS_T; + +#define DFU_FUNC_DESC_SIZE sizeof(USB_DFU_FUNC_DESCRIPTOR) +#define DFU_GET_STATUS_SIZE 0x6 + + +#endif /* __MW_USBD_DFU_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_dfuuser.h b/lpc_chip_15xx/inc/usbd/usbd_dfuuser.h new file mode 100644 index 0000000..61cd666 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_dfuuser.h @@ -0,0 +1,270 @@ +/*********************************************************************** +* $Id:: mw_usbd_dfuuser.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* Device Firmware Upgrade Class Custom User Module Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef __DFUUSER_H__ +#define __DFUUSER_H__ + +#include "usbd.h" +#include "usbd_dfu.h" +#include "usbd_core.h" + +/** \file + * \brief Device Firmware Upgrade (DFU) API structures and function prototypes. + * + * Definition of functions exported by ROM based DFU function driver. + * + */ + + +/** \ingroup Group_USBD + * @defgroup USBD_DFU Device Firmware Upgrade (DFU) Class Function Driver + * \section Sec_MSCModDescription Module Description + * DFU Class Function Driver module. This module contains an internal implementation of the USB DFU Class. + * User applications can use this class driver instead of implementing the DFU class manually + * via the low-level USBD_HW and USBD_Core APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB DFU Class. + */ + +/** \brief USB descriptors data structure. + * \ingroup USBD_DFU + * + * \details This module exposes functions which interact directly with USB device stack's core layer. + * The application layer uses this component when it has to implement custom class function driver or + * standard class function driver which is not part of the current USB device stack. + * The functions exposed by this interface are to register class specific EP0 handlers and corresponding + * utility functions to manipulate EP0 state machine of the stack. This interface also exposes + * function to register custom endpoint interrupt handler. + * + */ +typedef struct USBD_DFU_INIT_PARAM +{ + /* memory allocation params */ + uint32_t mem_base; /**< Base memory location from where the stack can allocate + data and buffers. \note The memory address set in this field + should be accessible by USB DMA controller. Also this value + should be aligned on 4 byte boundary. + */ + uint32_t mem_size; /**< The size of memory buffer which stack can use. + \note The \em mem_size should be greater than the size + returned by USBD_DFU_API::GetMemSize() routine.*/ + /* DFU paramas */ + uint16_t wTransferSize; /**< DFU transfer block size in number of bytes. + This value should match the value set in DFU descriptor + provided as part of the descriptor array + (\em high_speed_desc) passed to Init() through + \ref USB_CORE_DESCS_T structure. */ + + uint16_t pad; + /** Pointer to the DFU interface descriptor within the descriptor + * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T + * structure. + */ + uint8_t* intf_desc; + /* user defined functions */ + /** + * DFU Write callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a write command. For application using zero-copy buffer scheme + * this function is called for the first time with \em length parameter set to 0. + * The application code should update the buffer pointer. + * + * \param[in] block_num Destination start address. + * \param[in, out] src Pointer to a pointer to the source of data. Pointer-to-pointer + * is used to implement zero-copy buffers. See \ref USBD_ZeroCopy + * for more details on zero-copy concept. + * \param[out] bwPollTimeout Pointer to a 3 byte buffer which the callback implementer + * should fill with the amount of minimum time, in milliseconds, + * that the host should wait before sending a subsequent + * DFU_GETSTATUS request. + * \param[in] length Number of bytes to be written. + * \return Returns DFU_STATUS_ values defined in mw_usbd_dfu.h. + * + */ + uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout); + + /** + * DFU Read callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a read command. + * + * \param[in] block_num Destination start address. + * \param[in, out] dst Pointer to a pointer to the source of data. Pointer-to-pointer + * is used to implement zero-copy buffers. See \ref USBD_ZeroCopy + * for more details on zero-copy concept. + * \param[in] length Amount of data copied to destination buffer. + * \return Returns + * - DFU_STATUS_ values defined in mw_usbd_dfu.h to return error conditions. + * - 0 if there is no more data to be read. Stack will send EOF frame and set + * DFU state-machine to dfuIdle state. + * - length of the data copied, should be greater than or equal to 16. If the data copied + * is less than DFU \em wTransferSize the stack will send EOF frame and + * goes to dfuIdle state. + * + */ + uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length); + + /** + * DFU done callback function. + * + * This function is provided by the application software. This function gets called + * after firmware download completes. + * + * \return Nothing. + * + */ + void (*DFU_Done)(void); + + /** + * DFU detach callback function. + * + * This function is provided by the application software. This function gets called + * after USB_REQ_DFU_DETACH is received. Applications which set USB_DFU_WILL_DETACH + * bit in DFU descriptor should define this function. As part of this function + * application can call Connect() routine to disconnect and then connect back with + * host. For application which rely on WinUSB based host application should use this + * feature since USB reset can be invoked only by kernel drivers on Windows host. + * By implementing this feature host doen't have to issue reset instead the device + * has to do it automatically by disconnect and connect procedure. + * + * \param[in] hUsb Handle DFU control structure. + * \return Nothing. + * + */ + void (*DFU_Detach)(USBD_HANDLE_T hUsb); + + /** + * Optional user override-able function to replace the default DFU class handler. + * + * The application software could override the default EP0 class handler with their + * own by providing the handler function address as this data member of the parameter + * structure. Application which like the default handler should set this data member + * to zero before calling the USBD_DFU_API::Init(). + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*DFU_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + +} USBD_DFU_INIT_PARAM_T; + + +/** \brief DFU class API functions structure. + * \ingroup USBD_DFU + * + * This module exposes functions which interact directly with USB device controller hardware. + * + */ +typedef struct USBD_DFU_API +{ + /** \fn uint32_t GetMemSize(USBD_DFU_INIT_PARAM_T* param) + * Function to determine the memory required by the DFU function driver module. + * + * This function is called by application layer before calling pUsbApi->dfu->Init(), to allocate memory used + * by DFU function driver module. The application should allocate the memory which is accessible by USB + * controller/DMA controller. + * \note Some memory areas are not accessible by all bus masters. + * + * \param[in] param Structure containing DFU function driver module initialization parameters. + * \return Returns the required memory size in bytes. + */ + uint32_t (*GetMemSize)(USBD_DFU_INIT_PARAM_T* param); + + /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param) + * Function to initialize DFU function driver module. + * + * This function is called by application layer to initialize DFU function driver module. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in, out] param Structure containing DFU function driver module initialization parameters. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_BAD_MEM_BUF Memory buffer passed is not 4-byte aligned or smaller than required. + * \retval ERR_API_INVALID_PARAM2 Either DFU_Write() or DFU_Done() or DFU_Read() call-backs are not defined. + * \retval ERR_USBD_BAD_DESC + * - USB_DFU_DESCRIPTOR_TYPE is not defined immediately after + * interface descriptor. + * - wTransferSize in descriptor doesn't match the value passed + * in param->wTransferSize. + * - DFU_Detach() is not defined while USB_DFU_WILL_DETACH is set + * in DFU descriptor. + * \retval ERR_USBD_BAD_INTF_DESC Wrong interface descriptor is passed. + */ + ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state); + +} USBD_DFU_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes + *-----------------------------------------------------------------------------*/ +/** @cond ADVANCED_API */ + +typedef struct _USBD_DFU_CTRL_T +{ + /*ALIGNED(4)*/ DFU_STATUS_T dfu_req_get_status; + uint16_t pad; + uint8_t dfu_state; + uint8_t dfu_status; + uint8_t download_done; + uint8_t if_num; /* interface number */ + + uint8_t* xfr_buf; + USB_DFU_FUNC_DESCRIPTOR* dfu_desc; + + USB_CORE_CTRL_T* pUsbCtrl; + /* user defined functions */ + /* return DFU_STATUS_ values defined in mw_usbd_dfu.h */ + uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout); + /* return + * DFU_STATUS_ : values defined in mw_usbd_dfu.h in case of errors + * 0 : If end of memory reached + * length : Amount of data copied to destination buffer + */ + uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length); + /* callback called after download is finished */ + void (*DFU_Done)(void); + /* callback called after USB_REQ_DFU_DETACH is recived */ + void (*DFU_Detach)(USBD_HANDLE_T hUsb); + +} USBD_DFU_CTRL_T; + +/** @cond DIRECT_API */ +uint32_t mwDFU_GetMemSize(USBD_DFU_INIT_PARAM_T* param); +extern ErrorCode_t mwDFU_init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state); +/** @endcond */ + +/** @endcond */ + +#endif /* __DFUUSER_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_hid.h b/lpc_chip_15xx/inc/usbd/usbd_hid.h new file mode 100644 index 0000000..f0a4f3b --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_hid.h @@ -0,0 +1,431 @@ +/*********************************************************************** +* $Id: mw_usbd_hid.h.rca 1.2 Tue Nov 1 11:45:07 2011 nlv09221 Experimental $ +* +* Project: USB device ROM Stack +* +* Description: +* HID Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __HID_H__ +#define __HID_H__ + +#include "usbd.h" + +/** \file + * \brief Common definitions and declarations for the library USB HID Class driver. + * + * Common definitions and declarations for the library USB HID Class driver. + * \addtogroup USBD_HID + * @{ + */ + + +/** HID Subclass Codes + * @{ + */ +/** Descriptor Subclass value indicating that the device or interface does not implement a HID boot protocol. */ +#define HID_SUBCLASS_NONE 0x00 +/** Descriptor Subclass value indicating that the device or interface implements a HID boot protocol. */ +#define HID_SUBCLASS_BOOT 0x01 +/** @} */ + +/** HID Protocol Codes + * @{ + */ +/** Descriptor Protocol value indicating that the device or interface does not belong to a HID boot protocol. */ +#define HID_PROTOCOL_NONE 0x00 +/** Descriptor Protocol value indicating that the device or interface belongs to the Keyboard HID boot protocol. */ +#define HID_PROTOCOL_KEYBOARD 0x01 +/** Descriptor Protocol value indicating that the device or interface belongs to the Mouse HID boot protocol. */ +#define HID_PROTOCOL_MOUSE 0x02 +/** @} */ + + + +/** Descriptor Types + * @{ + */ +/** Descriptor header type value, to indicate a HID class HID descriptor. */ +#define HID_HID_DESCRIPTOR_TYPE 0x21 +/** Descriptor header type value, to indicate a HID class HID report descriptor. */ +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +/** Descriptor header type value, to indicate a HID class HID Physical descriptor. */ +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 +/** @} */ + + +/** \brief HID class-specific HID Descriptor. + * + * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID + * specification for details on the structure elements. + * + */ +PRE_PACK struct POST_PACK _HID_DESCRIPTOR { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of HID descriptor. */ + uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to. */ + uint8_t bCountryCode; /**< Country code of the localized device, or zero if universal. */ + uint8_t bNumDescriptors; /**< Total number of HID report descriptors for the interface. */ + + PRE_PACK struct POST_PACK _HID_DESCRIPTOR_LIST { + uint8_t bDescriptorType; /**< Type of HID report. */ + uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */ + } DescriptorList[1]; /**< Array of one or more descriptors */ +} ; +/** HID class-specific HID Descriptor. */ +typedef struct _HID_DESCRIPTOR HID_DESCRIPTOR; + +#define HID_DESC_SIZE sizeof(HID_DESCRIPTOR) + +/** HID Request Codes + * @{ + */ +#define HID_REQUEST_GET_REPORT 0x01 +#define HID_REQUEST_GET_IDLE 0x02 +#define HID_REQUEST_GET_PROTOCOL 0x03 +#define HID_REQUEST_SET_REPORT 0x09 +#define HID_REQUEST_SET_IDLE 0x0A +#define HID_REQUEST_SET_PROTOCOL 0x0B +/** @} */ + +/** HID Report Types + * @{ + */ +#define HID_REPORT_INPUT 0x01 +#define HID_REPORT_OUTPUT 0x02 +#define HID_REPORT_FEATURE 0x03 +/** @} */ + + +/** Usage Pages + * @{ + */ +#define HID_USAGE_PAGE_UNDEFINED 0x00 +#define HID_USAGE_PAGE_GENERIC 0x01 +#define HID_USAGE_PAGE_SIMULATION 0x02 +#define HID_USAGE_PAGE_VR 0x03 +#define HID_USAGE_PAGE_SPORT 0x04 +#define HID_USAGE_PAGE_GAME 0x05 +#define HID_USAGE_PAGE_DEV_CONTROLS 0x06 +#define HID_USAGE_PAGE_KEYBOARD 0x07 +#define HID_USAGE_PAGE_LED 0x08 +#define HID_USAGE_PAGE_BUTTON 0x09 +#define HID_USAGE_PAGE_ORDINAL 0x0A +#define HID_USAGE_PAGE_TELEPHONY 0x0B +#define HID_USAGE_PAGE_CONSUMER 0x0C +#define HID_USAGE_PAGE_DIGITIZER 0x0D +#define HID_USAGE_PAGE_UNICODE 0x10 +#define HID_USAGE_PAGE_ALPHANUMERIC 0x14 +/** @} */ + + +/** Generic Desktop Page (0x01) + * @{ + */ +#define HID_USAGE_GENERIC_POINTER 0x01 +#define HID_USAGE_GENERIC_MOUSE 0x02 +#define HID_USAGE_GENERIC_JOYSTICK 0x04 +#define HID_USAGE_GENERIC_GAMEPAD 0x05 +#define HID_USAGE_GENERIC_KEYBOARD 0x06 +#define HID_USAGE_GENERIC_KEYPAD 0x07 +#define HID_USAGE_GENERIC_X 0x30 +#define HID_USAGE_GENERIC_Y 0x31 +#define HID_USAGE_GENERIC_Z 0x32 +#define HID_USAGE_GENERIC_RX 0x33 +#define HID_USAGE_GENERIC_RY 0x34 +#define HID_USAGE_GENERIC_RZ 0x35 +#define HID_USAGE_GENERIC_SLIDER 0x36 +#define HID_USAGE_GENERIC_DIAL 0x37 +#define HID_USAGE_GENERIC_WHEEL 0x38 +#define HID_USAGE_GENERIC_HATSWITCH 0x39 +#define HID_USAGE_GENERIC_COUNTED_BUFFER 0x3A +#define HID_USAGE_GENERIC_BYTE_COUNT 0x3B +#define HID_USAGE_GENERIC_MOTION_WAKEUP 0x3C +#define HID_USAGE_GENERIC_VX 0x40 +#define HID_USAGE_GENERIC_VY 0x41 +#define HID_USAGE_GENERIC_VZ 0x42 +#define HID_USAGE_GENERIC_VBRX 0x43 +#define HID_USAGE_GENERIC_VBRY 0x44 +#define HID_USAGE_GENERIC_VBRZ 0x45 +#define HID_USAGE_GENERIC_VNO 0x46 +#define HID_USAGE_GENERIC_SYSTEM_CTL 0x80 +#define HID_USAGE_GENERIC_SYSCTL_POWER 0x81 +#define HID_USAGE_GENERIC_SYSCTL_SLEEP 0x82 +#define HID_USAGE_GENERIC_SYSCTL_WAKE 0x83 +#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU 0x84 +#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU 0x85 +#define HID_USAGE_GENERIC_SYSCTL_APP_MENU 0x86 +#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU 0x87 +#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT 0x88 +#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT 0x89 +#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT 0x8A +#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT 0x8B +#define HID_USAGE_GENERIC_SYSCTL_MENU_UP 0x8C +#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN 0x8D +/** @} */ + +/** Simulation Controls Page (0x02) + * @{ + */ +#define HID_USAGE_SIMULATION_RUDDER 0xBA +#define HID_USAGE_SIMULATION_THROTTLE 0xBB +/** @} */ + +/* Virtual Reality Controls Page (0x03) */ +/* ... */ + +/* Sport Controls Page (0x04) */ +/* ... */ + +/* Game Controls Page (0x05) */ +/* ... */ + +/* Generic Device Controls Page (0x06) */ +/* ... */ + +/** Keyboard/Keypad Page (0x07) + * @{ + */ +/** Error "keys" */ +#define HID_USAGE_KEYBOARD_NOEVENT 0x00 +#define HID_USAGE_KEYBOARD_ROLLOVER 0x01 +#define HID_USAGE_KEYBOARD_POSTFAIL 0x02 +#define HID_USAGE_KEYBOARD_UNDEFINED 0x03 + +/** Letters */ +#define HID_USAGE_KEYBOARD_aA 0x04 +#define HID_USAGE_KEYBOARD_zZ 0x1D + +/** Numbers */ +#define HID_USAGE_KEYBOARD_ONE 0x1E +#define HID_USAGE_KEYBOARD_ZERO 0x27 + +#define HID_USAGE_KEYBOARD_RETURN 0x28 +#define HID_USAGE_KEYBOARD_ESCAPE 0x29 +#define HID_USAGE_KEYBOARD_DELETE 0x2A + +/** Funtion keys */ +#define HID_USAGE_KEYBOARD_F1 0x3A +#define HID_USAGE_KEYBOARD_F12 0x45 + +#define HID_USAGE_KEYBOARD_PRINT_SCREEN 0x46 + +/** Modifier Keys */ +#define HID_USAGE_KEYBOARD_LCTRL 0xE0 +#define HID_USAGE_KEYBOARD_LSHFT 0xE1 +#define HID_USAGE_KEYBOARD_LALT 0xE2 +#define HID_USAGE_KEYBOARD_LGUI 0xE3 +#define HID_USAGE_KEYBOARD_RCTRL 0xE4 +#define HID_USAGE_KEYBOARD_RSHFT 0xE5 +#define HID_USAGE_KEYBOARD_RALT 0xE6 +#define HID_USAGE_KEYBOARD_RGUI 0xE7 +#define HID_USAGE_KEYBOARD_SCROLL_LOCK 0x47 +#define HID_USAGE_KEYBOARD_NUM_LOCK 0x53 +#define HID_USAGE_KEYBOARD_CAPS_LOCK 0x39 +/** @} */ + +/* ... */ + +/** LED Page (0x08) + * @{ + */ +#define HID_USAGE_LED_NUM_LOCK 0x01 +#define HID_USAGE_LED_CAPS_LOCK 0x02 +#define HID_USAGE_LED_SCROLL_LOCK 0x03 +#define HID_USAGE_LED_COMPOSE 0x04 +#define HID_USAGE_LED_KANA 0x05 +#define HID_USAGE_LED_POWER 0x06 +#define HID_USAGE_LED_SHIFT 0x07 +#define HID_USAGE_LED_DO_NOT_DISTURB 0x08 +#define HID_USAGE_LED_MUTE 0x09 +#define HID_USAGE_LED_TONE_ENABLE 0x0A +#define HID_USAGE_LED_HIGH_CUT_FILTER 0x0B +#define HID_USAGE_LED_LOW_CUT_FILTER 0x0C +#define HID_USAGE_LED_EQUALIZER_ENABLE 0x0D +#define HID_USAGE_LED_SOUND_FIELD_ON 0x0E +#define HID_USAGE_LED_SURROUND_FIELD_ON 0x0F +#define HID_USAGE_LED_REPEAT 0x10 +#define HID_USAGE_LED_STEREO 0x11 +#define HID_USAGE_LED_SAMPLING_RATE_DETECT 0x12 +#define HID_USAGE_LED_SPINNING 0x13 +#define HID_USAGE_LED_CAV 0x14 +#define HID_USAGE_LED_CLV 0x15 +#define HID_USAGE_LED_RECORDING_FORMAT_DET 0x16 +#define HID_USAGE_LED_OFF_HOOK 0x17 +#define HID_USAGE_LED_RING 0x18 +#define HID_USAGE_LED_MESSAGE_WAITING 0x19 +#define HID_USAGE_LED_DATA_MODE 0x1A +#define HID_USAGE_LED_BATTERY_OPERATION 0x1B +#define HID_USAGE_LED_BATTERY_OK 0x1C +#define HID_USAGE_LED_BATTERY_LOW 0x1D +#define HID_USAGE_LED_SPEAKER 0x1E +#define HID_USAGE_LED_HEAD_SET 0x1F +#define HID_USAGE_LED_HOLD 0x20 +#define HID_USAGE_LED_MICROPHONE 0x21 +#define HID_USAGE_LED_COVERAGE 0x22 +#define HID_USAGE_LED_NIGHT_MODE 0x23 +#define HID_USAGE_LED_SEND_CALLS 0x24 +#define HID_USAGE_LED_CALL_PICKUP 0x25 +#define HID_USAGE_LED_CONFERENCE 0x26 +#define HID_USAGE_LED_STAND_BY 0x27 +#define HID_USAGE_LED_CAMERA_ON 0x28 +#define HID_USAGE_LED_CAMERA_OFF 0x29 +#define HID_USAGE_LED_ON_LINE 0x2A +#define HID_USAGE_LED_OFF_LINE 0x2B +#define HID_USAGE_LED_BUSY 0x2C +#define HID_USAGE_LED_READY 0x2D +#define HID_USAGE_LED_PAPER_OUT 0x2E +#define HID_USAGE_LED_PAPER_JAM 0x2F +#define HID_USAGE_LED_REMOTE 0x30 +#define HID_USAGE_LED_FORWARD 0x31 +#define HID_USAGE_LED_REVERSE 0x32 +#define HID_USAGE_LED_STOP 0x33 +#define HID_USAGE_LED_REWIND 0x34 +#define HID_USAGE_LED_FAST_FORWARD 0x35 +#define HID_USAGE_LED_PLAY 0x36 +#define HID_USAGE_LED_PAUSE 0x37 +#define HID_USAGE_LED_RECORD 0x38 +#define HID_USAGE_LED_ERROR 0x39 +#define HID_USAGE_LED_SELECTED_INDICATOR 0x3A +#define HID_USAGE_LED_IN_USE_INDICATOR 0x3B +#define HID_USAGE_LED_MULTI_MODE_INDICATOR 0x3C +#define HID_USAGE_LED_INDICATOR_ON 0x3D +#define HID_USAGE_LED_INDICATOR_FLASH 0x3E +#define HID_USAGE_LED_INDICATOR_SLOW_BLINK 0x3F +#define HID_USAGE_LED_INDICATOR_FAST_BLINK 0x40 +#define HID_USAGE_LED_INDICATOR_OFF 0x41 +#define HID_USAGE_LED_FLASH_ON_TIME 0x42 +#define HID_USAGE_LED_SLOW_BLINK_ON_TIME 0x43 +#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME 0x44 +#define HID_USAGE_LED_FAST_BLINK_ON_TIME 0x45 +#define HID_USAGE_LED_FAST_BLINK_OFF_TIME 0x46 +#define HID_USAGE_LED_INDICATOR_COLOR 0x47 +#define HID_USAGE_LED_RED 0x48 +#define HID_USAGE_LED_GREEN 0x49 +#define HID_USAGE_LED_AMBER 0x4A +#define HID_USAGE_LED_GENERIC_INDICATOR 0x4B +/** @} */ + +/* Button Page (0x09) + */ +/* There is no need to label these usages. */ + +/* Ordinal Page (0x0A) + */ +/* There is no need to label these usages. */ + +/** Telephony Device Page (0x0B) + * @{ + */ +#define HID_USAGE_TELEPHONY_PHONE 0x01 +#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE 0x02 +#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS 0x03 +#define HID_USAGE_TELEPHONY_HANDSET 0x04 +#define HID_USAGE_TELEPHONY_HEADSET 0x05 +#define HID_USAGE_TELEPHONY_KEYPAD 0x06 +#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON 0x07 +/** @} */ +/* ... */ + +/** Consumer Page (0x0C) + * @{ + */ +#define HID_USAGE_CONSUMER_CONTROL 0x01 +#define HID_USAGE_CONSUMER_FAST_FORWARD 0xB3 +#define HID_USAGE_CONSUMER_REWIND 0xB4 +#define HID_USAGE_CONSUMER_PLAY_PAUSE 0xCD +#define HID_USAGE_CONSUMER_VOLUME_INCREMENT 0xE9 +#define HID_USAGE_CONSUMER_VOLUME_DECREMENT 0xEA +/** @} */ +/* ... */ + +/* and others ... */ + + +/** HID Report Item Macros + * @{ + */ +/** Main Items */ +#define HID_Input(x) 0x81,x +#define HID_Output(x) 0x91,x +#define HID_Feature(x) 0xB1,x +#define HID_Collection(x) 0xA1,x +#define HID_EndCollection 0xC0 + +/** Data (Input, Output, Feature) */ +#define HID_Data 0<<0 +#define HID_Constant 1<<0 +#define HID_Array 0<<1 +#define HID_Variable 1<<1 +#define HID_Absolute 0<<2 +#define HID_Relative 1<<2 +#define HID_NoWrap 0<<3 +#define HID_Wrap 1<<3 +#define HID_Linear 0<<4 +#define HID_NonLinear 1<<4 +#define HID_PreferredState 0<<5 +#define HID_NoPreferred 1<<5 +#define HID_NoNullPosition 0<<6 +#define HID_NullState 1<<6 +#define HID_NonVolatile 0<<7 +#define HID_Volatile 1<<7 + +/** Collection Data */ +#define HID_Physical 0x00 +#define HID_Application 0x01 +#define HID_Logical 0x02 +#define HID_Report 0x03 +#define HID_NamedArray 0x04 +#define HID_UsageSwitch 0x05 +#define HID_UsageModifier 0x06 + +/** Global Items */ +#define HID_UsagePage(x) 0x05,x +#define HID_UsagePageVendor(x) 0x06,x,0xFF +#define HID_LogicalMin(x) 0x15,x +#define HID_LogicalMinS(x) 0x16,(x&0xFF),((x>>8)&0xFF) +#define HID_LogicalMinL(x) 0x17,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) +#define HID_LogicalMax(x) 0x25,x +#define HID_LogicalMaxS(x) 0x26,(x&0xFF),((x>>8)&0xFF) +#define HID_LogicalMaxL(x) 0x27,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) +#define HID_PhysicalMin(x) 0x35,x +#define HID_PhysicalMinS(x) 0x36,(x&0xFF),((x>>8)&0xFF) +#define HID_PhysicalMinL(x) 0x37,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) +#define HID_PhysicalMax(x) 0x45,x +#define HID_PhysicalMaxS(x) 0x46,(x&0xFF),((x>>8)&0xFF) +#define HID_PhysicalMaxL(x) 0x47,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) +#define HID_UnitExponent(x) 0x55,x +#define HID_Unit(x) 0x65,x +#define HID_UnitS(x) 0x66,(x&0xFF),((x>>8)&0xFF) +#define HID_UnitL(x) 0x67,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF) +#define HID_ReportSize(x) 0x75,x +#define HID_ReportID(x) 0x85,x +#define HID_ReportCount(x) 0x95,x +#define HID_ReportCount16(x) 0x96,(x&0xFF),((x>>8)&0xFF) +#define HID_Push 0xA0 +#define HID_Pop 0xB0 + +/** Local Items */ +#define HID_Usage(x) 0x09,x +#define HID_UsageMin(x) 0x19,x +#define HID_UsageMax(x) 0x29,x +/** @} */ + +/** @} */ + +#endif /* __HID_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_hiduser.h b/lpc_chip_15xx/inc/usbd/usbd_hiduser.h new file mode 100644 index 0000000..c00ccac --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_hiduser.h @@ -0,0 +1,421 @@ +/*********************************************************************** +* $Id:: mw_usbd_hiduser.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* HID Custom User Module Definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef __HIDUSER_H__ +#define __HIDUSER_H__ + +#include "usbd.h" +#include "usbd_hid.h" +#include "usbd_core.h" + +/** \file + * \brief Human Interface Device (HID) API structures and function prototypes. + * + * Definition of functions exported by ROM based HID function driver. + * + */ + +/** \ingroup Group_USBD + * @defgroup USBD_HID HID Class Function Driver + * \section Sec_HIDModDescription Module Description + * HID Class Function Driver module. This module contains an internal implementation of the USB HID Class. + * User applications can use this class driver instead of implementing the HID class manually + * via the low-level HW and core APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB HID Class. + */ + +/** \brief HID report descriptor data structure. + * \ingroup USBD_HID + * + * \details This structure is used as part of HID function driver initialization + * parameter structure \ref USBD_HID_INIT_PARAM. This structure contains + * details of a report type supported by the application. An application + * can support multiple report types as a single HID device. The application + * should define this report type data structure per report it supports and + * the array of report types to USBD_HID_API::init() through \ref USBD_HID_INIT_PARAM + * structure. + * + * \note All descriptor pointers assigned in this structure should be on 4 byte + * aligned address boundary. + * + */ +typedef struct _HID_REPORT_T { + uint16_t len; /**< Size of the report descriptor in bytes. */ + uint8_t idle_time; /**< This value is used by stack to respond to Set_Idle & + GET_Idle requests for the specified report ID. The value + of this field specified the rate at which duplicate reports + are generated for the specified Report ID. For example, a + device with two input reports could specify an idle rate of + 20 milliseconds for report ID 1 and 500 milliseconds for + report ID 2. + */ + uint8_t __pad; /**< Padding space. */ + uint8_t* desc; /**< Report descriptor. */ +} USB_HID_REPORT_T; + +/** \brief USB descriptors data structure. + * \ingroup USBD_HID + * + * \details This module exposes functions which interact directly with USB device stack's core layer. + * The application layer uses this component when it has to implement custom class function driver or + * standard class function driver which is not part of the current USB device stack. + * The functions exposed by this interface are to register class specific EP0 handlers and corresponding + * utility functions to manipulate EP0 state machine of the stack. This interface also exposes + * function to register custom endpoint interrupt handler. + * + */ +typedef struct USBD_HID_INIT_PARAM +{ + /* memory allocation params */ + uint32_t mem_base; /**< Base memory location from where the stack can allocate + data and buffers. \note The memory address set in this field + should be accessible by USB DMA controller. Also this value + should be aligned on 4 byte boundary. + */ + uint32_t mem_size; /**< The size of memory buffer which stack can use. + \note The \em mem_size should be greater than the size + returned by USBD_HID_API::GetMemSize() routine.*/ + /* HID paramas */ + uint8_t max_reports; /**< Number of HID reports supported by this instance + of HID class driver. + */ + uint8_t pad[3]; + uint8_t* intf_desc; /**< Pointer to the HID interface descriptor within the + descriptor array (\em high_speed_desc) passed to Init() + through \ref USB_CORE_DESCS_T structure. + */ + USB_HID_REPORT_T* report_data; /**< Pointer to an array of HID report descriptor + data structure (\ref USB_HID_REPORT_T). The number + of elements in the array should be same a \em max_reports + value. The stack uses this array to respond to + requests received for various HID report descriptor + information. \note This array should be of global scope. + */ + + /* user defined functions */ + /* required functions */ + /** + * HID get report callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a HID_REQUEST_GET_REPORT request. The setup packet data (\em pSetup) + * is passed to the callback so that application can extract the report ID, report + * type and other information need to generate the report. \note HID reports are sent + * via interrupt IN endpoint also. This function is called only when report request + * is received on control endpoint. Application should implement \em HID_EpIn_Hdlr to + * send reports to host via interrupt IN endpoint. + * + * + * \param[in] hHid Handle to HID function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in, out] pBuffer Pointer to a pointer of data buffer containing report data. + * Pointer-to-pointer is used to implement zero-copy buffers. + * See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in] length Amount of data copied to destination buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_GetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); + + /** + * HID set report callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a HID_REQUEST_SET_REPORT request. The setup packet data (\em pSetup) + * is passed to the callback so that application can extract the report ID, report + * type and other information need to modify the report. An application might choose + * to ignore input Set_Report requests as meaningless. Alternatively these reports + * could be used to reset the origin of a control (that is, current position should + * report zero). + * + * \param[in] hHid Handle to HID function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in, out] pBuffer Pointer to a pointer of data buffer containing report data. + * Pointer-to-pointer is used to implement zero-copy buffers. + * See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in] length Amount of data copied to destination buffer. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_SetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length); + + /* optional functions */ + + /** + * Optional callback function to handle HID_GetPhysDesc request. + * + * The application software could provide this callback HID_GetPhysDesc handler to + * handle get physical descriptor requests sent by the host. When host requests + * Physical Descriptor set 0, application should return a special descriptor + * identifying the number of descriptor sets and their sizes. A Get_Descriptor + * request with the Physical Index equal to 1 should return the first Physical + * Descriptor set. A device could possibly have alternate uses for its items. + * These can be enumerated by issuing subsequent Get_Descriptor requests while + * incrementing the Descriptor Index. A device should return the last descriptor + * set to requests with an index greater than the last number defined in the HID + * descriptor. + * \note Applications which don't have physical descriptor should set this data member + * to zero before calling the USBD_HID_API::Init(). + * \n + * + * \param[in] hHid Handle to HID function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in] pBuf Pointer to a pointer of data buffer containing physical descriptor + * data. If the physical descriptor is in USB accessible memory area + * application could just update the pointer or else it should copy + * the descriptor to the address pointed by this pointer. + * \param[in] length Amount of data copied to destination buffer or descriptor length. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_GetPhysDesc)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length); + + /** + * Optional callback function to handle HID_REQUEST_SET_IDLE request. + * + * The application software could provide this callback to handle HID_REQUEST_SET_IDLE + * requests sent by the host. This callback is provided to applications to adjust + * timers associated with various reports, which are sent to host over interrupt + * endpoint. The setup packet data (\em pSetup) is passed to the callback so that + * application can extract the report ID, report type and other information need + * to modify the report's idle time. + * \note Applications which don't send reports on Interrupt endpoint or don't + * have idle time between reports should set this data member to zero before + * calling the USBD_HID_API::Init(). + * \n + * + * \param[in] hHid Handle to HID function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in] idleTime Idle time to be set for the specified report. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_SetIdle)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t idleTime); + + /** + * Optional callback function to handle HID_REQUEST_SET_PROTOCOL request. + * + * The application software could provide this callback to handle HID_REQUEST_SET_PROTOCOL + * requests sent by the host. This callback is provided to applications to adjust + * modes of their code between boot mode and report mode. + * \note Applications which don't support protocol modes should set this data member + * to zero before calling the USBD_HID_API::Init(). + * \n + * + * \param[in] hHid Handle to HID function driver. + * \param[in] pSetup Pointer to setup packet received from host. + * \param[in] protocol Protocol mode. + * 0 = Boot Protocol + * 1 = Report Protocol + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_SetProtocol)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t protocol); + + /** + * Optional Interrupt IN endpoint event handler. + * + * The application software could provide Interrupt IN endpoint event handler. + * Application which send reports to host on interrupt endpoint should provide + * an endpoint event handler through this data member. This data member is + * ignored if the interface descriptor \em intf_desc doesn't have any IN interrupt + * endpoint descriptor associated. + * \n + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Handle to HID function driver. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should return \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_EpIn_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + /** + * Optional Interrupt OUT endpoint event handler. + * + * The application software could provide Interrupt OUT endpoint event handler. + * Application which receives reports from host on interrupt endpoint should provide + * an endpoint event handler through this data member. This data member is + * ignored if the interface descriptor \em intf_desc doesn't have any OUT interrupt + * endpoint descriptor associated. + * \n + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Handle to HID function driver. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should return \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_EpOut_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + + /* user override-able function */ + /** + * Optional user override-able function to replace the default HID_GetReportDesc handler. + * + * The application software could override the default HID_GetReportDesc handler with their + * own by providing the handler function address as this data member of the parameter + * structure. Application which like the default handler should set this data member + * to zero before calling the USBD_HID_API::Init() and also provide report data array + * \em report_data field. + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_GetReportDesc)(USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length); + /** + * Optional user override-able function to replace the default HID class handler. + * + * The application software could override the default EP0 class handler with their + * own by providing the handler function address as this data member of the parameter + * structure. Application which like the default handler should set this data member + * to zero before calling the USBD_HID_API::Init(). + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*HID_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + +} USBD_HID_INIT_PARAM_T; + +/** \brief HID class API functions structure. + * \ingroup USBD_HID + * + * This structure contains pointers to all the function exposed by HID function driver module. + * + */ +typedef struct USBD_HID_API +{ + /** \fn uint32_t GetMemSize(USBD_HID_INIT_PARAM_T* param) + * Function to determine the memory required by the HID function driver module. + * + * This function is called by application layer before calling pUsbApi->hid->Init(), to allocate memory used + * by HID function driver module. The application should allocate the memory which is accessible by USB + * controller/DMA controller. + * \note Some memory areas are not accessible by all bus masters. + * + * \param[in] param Structure containing HID function driver module initialization parameters. + * \return Returns the required memory size in bytes. + */ + uint32_t (*GetMemSize)(USBD_HID_INIT_PARAM_T* param); + + /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param) + * Function to initialize HID function driver module. + * + * This function is called by application layer to initialize HID function driver + * module. On successful initialization the function returns a handle to HID + * function driver module in passed param structure. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in, out] param Structure containing HID function driver module + * initialization parameters. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_BAD_MEM_BUF Memory buffer passed is not 4-byte + * aligned or smaller than required. + * \retval ERR_API_INVALID_PARAM2 Either HID_GetReport() or HID_SetReport() + * callback are not defined. + * \retval ERR_USBD_BAD_DESC HID_HID_DESCRIPTOR_TYPE is not defined + * immediately after interface descriptor. + * \retval ERR_USBD_BAD_INTF_DESC Wrong interface descriptor is passed. + * \retval ERR_USBD_BAD_EP_DESC Wrong endpoint descriptor is passed. + */ + ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param); + +} USBD_HID_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes + *-----------------------------------------------------------------------------*/ +/** @cond ADVANCED_API */ + +typedef struct _HID_CTRL_T { + /* pointer to controller */ + USB_CORE_CTRL_T* pUsbCtrl; + /* descriptor pointers */ + uint8_t* hid_desc; + USB_HID_REPORT_T* report_data; + + uint8_t protocol; + uint8_t if_num; /* interface number */ + uint8_t epin_adr; /* IN interrupt endpoint */ + uint8_t epout_adr; /* OUT interrupt endpoint */ + + /* user defined functions */ + ErrorCode_t (*HID_GetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); + ErrorCode_t (*HID_SetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length); + ErrorCode_t (*HID_GetPhysDesc)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length); + ErrorCode_t (*HID_SetIdle)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t idleTime); + ErrorCode_t (*HID_SetProtocol)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t protocol); + + /* virtual overridable functions */ + ErrorCode_t (*HID_GetReportDesc)(USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length); + +}USB_HID_CTRL_T; + +/** @cond DIRECT_API */ +extern uint32_t mwHID_GetMemSize(USBD_HID_INIT_PARAM_T* param); +extern ErrorCode_t mwHID_init(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param); +/** @endcond */ + +/** @endcond */ + +#endif /* __HIDUSER_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_hw.h b/lpc_chip_15xx/inc/usbd/usbd_hw.h new file mode 100644 index 0000000..b7e0f10 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_hw.h @@ -0,0 +1,457 @@ +/*********************************************************************** +* $Id:: mw_usbd_hw.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* USB Hardware Function prototypes. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __USBHW_H__ +#define __USBHW_H__ + +#include "error.h" +#include "usbd.h" +#include "usbd_core.h" + +/** \file + * \brief USB Hardware Function prototypes. + * + * Definition of functions exported by ROM based Device Controller Driver (DCD). + * + */ + +/** \ingroup Group_USBD + * @defgroup USBD_HW USB Device Controller Driver + * \section Sec_HWModDescription Module Description + * The Device Controller Driver Layer implements the routines to deal directly with the hardware. + */ + +/** \ingroup USBD_HW +* USB Endpoint/class handler Callback Events. +* +*/ +enum USBD_EVENT_T { + USB_EVT_SETUP =1, /**< 1 Setup Packet received */ + USB_EVT_OUT, /**< 2 OUT Packet received */ + USB_EVT_IN, /**< 3 IN Packet sent */ + USB_EVT_OUT_NAK, /**< 4 OUT Packet - Not Acknowledged */ + USB_EVT_IN_NAK, /**< 5 IN Packet - Not Acknowledged */ + USB_EVT_OUT_STALL, /**< 6 OUT Packet - Stalled */ + USB_EVT_IN_STALL, /**< 7 IN Packet - Stalled */ + USB_EVT_OUT_DMA_EOT, /**< 8 DMA OUT EP - End of Transfer */ + USB_EVT_IN_DMA_EOT, /**< 9 DMA IN EP - End of Transfer */ + USB_EVT_OUT_DMA_NDR, /**< 10 DMA OUT EP - New Descriptor Request */ + USB_EVT_IN_DMA_NDR, /**< 11 DMA IN EP - New Descriptor Request */ + USB_EVT_OUT_DMA_ERR, /**< 12 DMA OUT EP - Error */ + USB_EVT_IN_DMA_ERR, /**< 13 DMA IN EP - Error */ + USB_EVT_RESET, /**< 14 Reset event recieved */ + USB_EVT_SOF, /**< 15 Start of Frame event */ + USB_EVT_DEV_STATE, /**< 16 Device status events */ + USB_EVT_DEV_ERROR /**< 17 Device error events */ +}; + +/** + * \brief Hardware API functions structure. + * \ingroup USBD_HW + * + * This module exposes functions which interact directly with USB device controller hardware. + * + */ +typedef struct USBD_HW_API +{ + /** \fn uint32_t GetMemSize(USBD_API_INIT_PARAM_T* param) + * Function to determine the memory required by the USB device stack's DCD and core layers. + * + * This function is called by application layer before calling pUsbApi->hw->Init(), to allocate memory used + * by DCD and core layers. The application should allocate the memory which is accessible by USB + * controller/DMA controller. + * \note Some memory areas are not accessible by all bus masters. + * + * \param[in] param Structure containing USB device stack initialization parameters. + * \return Returns the required memory size in bytes. + */ + uint32_t (*GetMemSize)(USBD_API_INIT_PARAM_T* param); + + /** \fn ErrorCode_t Init(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param) + * Function to initialize USB device stack's DCD and core layers. + * + * This function is called by application layer to initialize USB hardware and core layers. + * On successful initialization the function returns a handle to USB device stack which should + * be passed to the rest of the functions. + * + * \param[in,out] phUsb Pointer to the USB device stack handle of type USBD_HANDLE_T. + * \param[in] pDesc Structure containing pointers to various descriptor arrays needed by the stack. + * These descriptors are reported to USB host as part of enumerations process. + * \param[in] param Structure containing USB device stack initialization parameters. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK(0) On success + * \retval ERR_USBD_BAD_MEM_BUF(0x0004000b) When insufficient memory buffer is passed or memory + * is not aligned on 2048 boundary. + */ + ErrorCode_t (*Init)(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param); + + /** \fn void Connect(USBD_HANDLE_T hUsb, uint32_t con) + * Function to make USB device visible/invisible on the USB bus. + * + * This function is called after the USB initialization. This function uses the soft connect + * feature to make the device visible on the USB bus. This function is called only after the + * application is ready to handle the USB data. The enumeration process is started by the + * host after the device detection. The driver handles the enumeration process according to + * the USB descriptors passed in the USB initialization function. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] con States whether to connect (1) or to disconnect (0). + * \return Nothing. + */ + void (*Connect)(USBD_HANDLE_T hUsb, uint32_t con); + + /** \fn void ISR(USBD_HANDLE_T hUsb) + * Function to USB device controller interrupt events. + * + * When the user application is active the interrupt handlers are mapped in the user flash + * space. The user application must provide an interrupt handler for the USB interrupt and + * call this function in the interrupt handler routine. The driver interrupt handler takes + * appropriate action according to the data received on the USB bus. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*ISR)(USBD_HANDLE_T hUsb); + + /** \fn void Reset(USBD_HANDLE_T hUsb) + * Function to Reset USB device stack and hardware controller. + * + * Reset USB device stack and hardware controller. Disables all endpoints except EP0. + * Clears all pending interrupts and resets endpoint transfer queues. + * This function is called internally by pUsbApi->hw->init() and from reset event. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*Reset)(USBD_HANDLE_T hUsb); + + /** \fn void ForceFullSpeed(USBD_HANDLE_T hUsb, uint32_t cfg) + * Function to force high speed USB device to operate in full speed mode. + * + * This function is useful for testing the behavior of current device when connected + * to a full speed only hosts. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] cfg When 1 - set force full-speed or + * 0 - clear force full-speed. + * \return Nothing. + */ + void (*ForceFullSpeed )(USBD_HANDLE_T hUsb, uint32_t cfg); + + /** \fn void WakeUpCfg(USBD_HANDLE_T hUsb, uint32_t cfg) + * Function to configure USB device controller to wake-up host on remote events. + * + * This function is called by application layer to configure the USB device controller + * to wakeup on remote events. It is recommended to call this function from users's + * USB_WakeUpCfg() callback routine registered with stack. + * \note User's USB_WakeUpCfg() is registered with stack by setting the USB_WakeUpCfg member + * of USBD_API_INIT_PARAM_T structure before calling pUsbApi->hw->Init() routine. + * Certain USB device controllers needed to keep some clocks always on to generate + * resume signaling through pUsbApi->hw->WakeUp(). This hook is provided to support + * such controllers. In most controllers cases this is an empty routine. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] cfg When 1 - Configure controller to wake on remote events or + * 0 - Configure controller not to wake on remote events. + * \return Nothing. + */ + void (*WakeUpCfg)(USBD_HANDLE_T hUsb, uint32_t cfg); + + /** \fn void SetAddress(USBD_HANDLE_T hUsb, uint32_t adr) + * Function to set USB address assigned by host in device controller hardware. + * + * This function is called automatically when USB_REQUEST_SET_ADDRESS request is received + * by the stack from USB host. + * This interface is provided to users to invoke this function in other scenarios which are not + * handle by current stack. In most user applications this function is not called directly. + * Also this function can be used by users who are selectively modifying the USB device stack's + * standard handlers through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] adr USB bus Address to which the device controller should respond. Usually + * assigned by the USB host. + * \return Nothing. + */ + void (*SetAddress)(USBD_HANDLE_T hUsb, uint32_t adr); + + /** \fn void Configure(USBD_HANDLE_T hUsb, uint32_t cfg) + * Function to configure device controller hardware with selected configuration. + * + * This function is called automatically when USB_REQUEST_SET_CONFIGURATION request is received + * by the stack from USB host. + * This interface is provided to users to invoke this function in other scenarios which are not + * handle by current stack. In most user applications this function is not called directly. + * Also this function can be used by users who are selectively modifying the USB device stack's + * standard handlers through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] cfg Configuration index. + * \return Nothing. + */ + void (*Configure)(USBD_HANDLE_T hUsb, uint32_t cfg); + + /** \fn void ConfigEP(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD) + * Function to configure USB Endpoint according to descriptor. + * + * This function is called automatically when USB_REQUEST_SET_CONFIGURATION request is received + * by the stack from USB host. All the endpoints associated with the selected configuration + * are configured. + * This interface is provided to users to invoke this function in other scenarios which are not + * handle by current stack. In most user applications this function is not called directly. + * Also this function can be used by users who are selectively modifying the USB device stack's + * standard handlers through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] pEPD Endpoint descriptor structure defined in USB 2.0 specification. + * \return Nothing. + */ + void (*ConfigEP)(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD); + + /** \fn void DirCtrlEP(USBD_HANDLE_T hUsb, uint32_t dir) + * Function to set direction for USB control endpoint EP0. + * + * This function is called automatically by the stack on need basis. + * This interface is provided to users to invoke this function in other scenarios which are not + * handle by current stack. In most user applications this function is not called directly. + * Also this function can be used by users who are selectively modifying the USB device stack's + * standard handlers through callback interface exposed by the stack. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] cfg When 1 - Set EP0 in IN transfer mode + * 0 - Set EP0 in OUT transfer mode + * \return Nothing. + */ + void (*DirCtrlEP)(USBD_HANDLE_T hUsb, uint32_t dir); + + /** \fn void EnableEP(USBD_HANDLE_T hUsb, uint32_t EPNum) + * Function to enable selected USB endpoint. + * + * This function enables interrupts on selected endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \return Nothing. + */ + void (*EnableEP)(USBD_HANDLE_T hUsb, uint32_t EPNum); + + /** \fn void DisableEP(USBD_HANDLE_T hUsb, uint32_t EPNum) + * Function to disable selected USB endpoint. + * + * This function disables interrupts on selected endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \return Nothing. + */ + void (*DisableEP)(USBD_HANDLE_T hUsb, uint32_t EPNum); + + /** \fn void ResetEP(USBD_HANDLE_T hUsb, uint32_t EPNum) + * Function to reset selected USB endpoint. + * + * This function flushes the endpoint buffers and resets data toggle logic. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \return Nothing. + */ + void (*ResetEP)(USBD_HANDLE_T hUsb, uint32_t EPNum); + + /** \fn void SetStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum) + * Function to STALL selected USB endpoint. + * + * Generates STALL signaling for requested endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \return Nothing. + */ + void (*SetStallEP)(USBD_HANDLE_T hUsb, uint32_t EPNum); + + /** \fn void ClrStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum) + * Function to clear STALL state for the requested endpoint. + * + * This function clears STALL state for the requested endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \return Nothing. + */ + void (*ClrStallEP)(USBD_HANDLE_T hUsb, uint32_t EPNum); + + /** \fn ErrorCode_t SetTestMode(USBD_HANDLE_T hUsb, uint8_t mode) + * Function to set high speed USB device controller in requested test mode. + * + * USB-IF requires the high speed device to be put in various test modes + * for electrical testing. This USB device stack calls this function whenever + * it receives USB_REQUEST_CLEAR_FEATURE request for USB_FEATURE_TEST_MODE. + * Users can put the device in test mode by directly calling this function. + * Returns ERR_USBD_INVALID_REQ when device controller is full-speed only. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] mode Test mode defined in USB 2.0 electrical testing specification. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK(0) - On success + * \retval ERR_USBD_INVALID_REQ(0x00040001) - Invalid test mode or + * Device controller is full-speed only. + */ + ErrorCode_t (*SetTestMode)(USBD_HANDLE_T hUsb, uint8_t mode); + + /** \fn uint32_t ReadEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData) + * Function to read data received on the requested endpoint. + * + * This function is called by USB stack and the application layer to read the data + * received on the requested endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \param[in,out] pData Pointer to the data buffer where data is to be copied. + * \return Returns the number of bytes copied to the buffer. + */ + uint32_t (*ReadEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData); + + /** \fn uint32_t ReadReqEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len) + * Function to queue read request on the specified endpoint. + * + * This function is called by USB stack and the application layer to queue a read request + * on the specified endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \param[in,out] pData Pointer to the data buffer where data is to be copied. This buffer + * address should be accessible by USB DMA master. + * \param[in] len Length of the buffer passed. + * \return Returns the length of the requested buffer. + */ + uint32_t (*ReadReqEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len); + + /** \fn uint32_t ReadSetupPkt(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t *pData) + * Function to read setup packet data received on the requested endpoint. + * + * This function is called by USB stack and the application layer to read setup packet data + * received on the requested endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP0_IN is represented by 0x80 number. + * \param[in,out] pData Pointer to the data buffer where data is to be copied. + * \return Returns the number of bytes copied to the buffer. + */ + uint32_t (*ReadSetupPkt)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t *pData); + + /** \fn uint32_t WriteEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt) + * Function to write data to be sent on the requested endpoint. + * + * This function is called by USB stack and the application layer to send data + * on the requested endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number as per USB specification. + * ie. An EP1_IN is represented by 0x81 number. + * \param[in] pData Pointer to the data buffer from where data is to be copied. + * \param[in] cnt Number of bytes to write. + * \return Returns the number of bytes written. + */ + uint32_t (*WriteEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt); + + /** \fn void WakeUp(USBD_HANDLE_T hUsb) + * Function to generate resume signaling on bus for remote host wakeup. + * + * This function is called by application layer to remotely wakeup host controller + * when system is in suspend state. Application should indicate this remote wakeup + * capability by setting USB_CONFIG_REMOTE_WAKEUP in bmAttributes of Configuration + * Descriptor. Also this routine will generate resume signalling only if host + * enables USB_FEATURE_REMOTE_WAKEUP by sending SET_FEATURE request before suspending + * the bus. + * + * \param[in] hUsb Handle to the USB device stack. + * \return Nothing. + */ + void (*WakeUp)(USBD_HANDLE_T hUsb); + + /** \fn void EnableEvent(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t event_type, uint32_t enable) + * Function to enable/disable selected USB event. + * + * This function enables interrupts on selected endpoint. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] EPNum Endpoint number corresponding to the event. + * ie. An EP1_IN is represented by 0x81 number. For device events + * set this param to 0x0. + * \param[in] event_type Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \param[in] enable 1 - enable event, 0 - disable event. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK(0) - On success + * \retval ERR_USBD_INVALID_REQ(0x00040001) - Invalid event type. + */ + ErrorCode_t (*EnableEvent)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t event_type, uint32_t enable); + +} USBD_HW_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes used by stack internally + *-----------------------------------------------------------------------------*/ +/** @cond DIRECT_API */ + +/* Driver functions */ +uint32_t hwUSB_GetMemSize(USBD_API_INIT_PARAM_T* param); +ErrorCode_t hwUSB_Init(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param); +void hwUSB_Connect(USBD_HANDLE_T hUsb, uint32_t con); +void hwUSB_ISR(USBD_HANDLE_T hUsb); + +/* USB Hardware Functions */ +extern void hwUSB_Reset(USBD_HANDLE_T hUsb); +extern void hwUSB_ForceFullSpeed (USBD_HANDLE_T hUsb, uint32_t con); +extern void hwUSB_WakeUpCfg(USBD_HANDLE_T hUsb, uint32_t cfg); +extern void hwUSB_SetAddress(USBD_HANDLE_T hUsb, uint32_t adr); +extern void hwUSB_Configure(USBD_HANDLE_T hUsb, uint32_t cfg); +extern void hwUSB_ConfigEP(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD); +extern void hwUSB_DirCtrlEP(USBD_HANDLE_T hUsb, uint32_t dir); +extern void hwUSB_EnableEP(USBD_HANDLE_T hUsb, uint32_t EPNum); +extern void hwUSB_DisableEP(USBD_HANDLE_T hUsb, uint32_t EPNum); +extern void hwUSB_ResetEP(USBD_HANDLE_T hUsb, uint32_t EPNum); +extern void hwUSB_SetStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum); +extern void hwUSB_ClrStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum); +extern ErrorCode_t hwUSB_SetTestMode(USBD_HANDLE_T hUsb, uint8_t mode); /* for FS only devices return ERR_USBD_INVALID_REQ */ +extern uint32_t hwUSB_ReadEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData); +extern uint32_t hwUSB_ReadReqEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len); +extern uint32_t hwUSB_ReadSetupPkt(USBD_HANDLE_T hUsb, uint32_t, uint32_t *); +extern uint32_t hwUSB_WriteEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt); + +/* generate resume signaling on the bus */ +extern void hwUSB_WakeUp(USBD_HANDLE_T hUsb); +extern ErrorCode_t hwUSB_EnableEvent(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t event_type, uint32_t enable); +/* TODO implement following routines +- function to program TD and queue them to ep Qh +*/ + +/** @endcond */ + + +#endif /* __USBHW_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_msc.h b/lpc_chip_15xx/inc/usbd/usbd_msc.h new file mode 100644 index 0000000..d17e150 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_msc.h @@ -0,0 +1,119 @@ +/*********************************************************************** +* $Id:: mw_usbd_msc.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* Mass Storage Class definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ + +#ifndef __MSC_H__ +#define __MSC_H__ + +#include "usbd.h" + +/** \file + * \brief Mass Storage class (MSC) descriptors. + * + * Definition of MSC class descriptors and their bit defines. + * + */ + +/* MSC Subclass Codes */ +#define MSC_SUBCLASS_RBC 0x01 +#define MSC_SUBCLASS_SFF8020I_MMC2 0x02 +#define MSC_SUBCLASS_QIC157 0x03 +#define MSC_SUBCLASS_UFI 0x04 +#define MSC_SUBCLASS_SFF8070I 0x05 +#define MSC_SUBCLASS_SCSI 0x06 + +/* MSC Protocol Codes */ +#define MSC_PROTOCOL_CBI_INT 0x00 +#define MSC_PROTOCOL_CBI_NOINT 0x01 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + + +/* MSC Request Codes */ +#define MSC_REQUEST_RESET 0xFF +#define MSC_REQUEST_GET_MAX_LUN 0xFE + + +/* MSC Bulk-only Stage */ +#define MSC_BS_CBW 0 /* Command Block Wrapper */ +#define MSC_BS_DATA_OUT 1 /* Data Out Phase */ +#define MSC_BS_DATA_IN 2 /* Data In Phase */ +#define MSC_BS_DATA_IN_LAST 3 /* Data In Last Phase */ +#define MSC_BS_DATA_IN_LAST_STALL 4 /* Data In Last Phase with Stall */ +#define MSC_BS_CSW 5 /* Command Status Wrapper */ +#define MSC_BS_ERROR 6 /* Error */ + + +/* Bulk-only Command Block Wrapper */ +PRE_PACK struct POST_PACK _MSC_CBW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; +} ; +typedef struct _MSC_CBW MSC_CBW; + +/* Bulk-only Command Status Wrapper */ +PRE_PACK struct POST_PACK _MSC_CSW +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; +} ; +typedef struct _MSC_CSW MSC_CSW; + +#define MSC_CBW_Signature 0x43425355 +#define MSC_CSW_Signature 0x53425355 + + +/* CSW Status Definitions */ +#define CSW_CMD_PASSED 0x00 +#define CSW_CMD_FAILED 0x01 +#define CSW_PHASE_ERROR 0x02 + + +/* SCSI Commands */ +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_MEDIA_REMOVAL 0x1E +#define SCSI_READ_FORMAT_CAPACITIES 0x23 +#define SCSI_READ_CAPACITY 0x25 +#define SCSI_READ10 0x28 +#define SCSI_WRITE10 0x2A +#define SCSI_VERIFY10 0x2F +#define SCSI_READ12 0xA8 +#define SCSI_WRITE12 0xAA +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE10 0x5A + + +#endif /* __MSC_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_mscuser.h b/lpc_chip_15xx/inc/usbd/usbd_mscuser.h new file mode 100644 index 0000000..1010707 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_mscuser.h @@ -0,0 +1,270 @@ +/*********************************************************************** +* $Id:: mw_usbd_mscuser.h 577 2012-11-20 01:42:04Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* Mass Storage Class Custom User Module definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __MSCUSER_H__ +#define __MSCUSER_H__ + +#include "error.h" +#include "usbd.h" +#include "usbd_msc.h" +#include "usbd_core.h" +#include "app_usbd_cfg.h" + +/** \file + * \brief Mass Storage Class (MSC) API structures and function prototypes. + * + * Definition of functions exported by ROM based MSC function driver. + * + */ + +/** \ingroup Group_USBD + * @defgroup USBD_MSC Mass Storage Class (MSC) Function Driver + * \section Sec_MSCModDescription Module Description + * MSC Class Function Driver module. This module contains an internal implementation of the USB MSC Class. + * User applications can use this class driver instead of implementing the MSC class manually + * via the low-level USBD_HW and USBD_Core APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB MSC Class. + */ + +/** \brief Mass Storage class function driver initialization parameter data structure. + * \ingroup USBD_MSC + * + * \details This data structure is used to pass initialization parameters to the + * Mass Storage class function driver's init function. + * + */ +typedef struct USBD_MSC_INIT_PARAM +{ + /* memory allocation params */ + uint32_t mem_base; /**< Base memory location from where the stack can allocate + data and buffers. \note The memory address set in this field + should be accessible by USB DMA controller. Also this value + should be aligned on 4 byte boundary. + */ + uint32_t mem_size; /**< The size of memory buffer which stack can use. + \note The \em mem_size should be greater than the size + returned by USBD_MSC_API::GetMemSize() routine.*/ + /* mass storage params */ + uint8_t* InquiryStr; /**< Pointer to the 28 character string. This string is + sent in response to the SCSI Inquiry command. \note The data + pointed by the pointer should be of global scope. + */ + uint32_t BlockCount; /**< Number of blocks present in the mass storage device */ + uint32_t BlockSize; /**< Block size in number of bytes */ + uint32_t MemorySize; /**< Memory size in number of bytes */ + /** Pointer to the interface descriptor within the descriptor + * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T + * structure. The stack assumes both HS and FS use same BULK endpoints. + */ + + uint8_t* intf_desc; + /* user defined functions */ + + /** + * MSC Write callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a write command. + * + * \param[in] offset Destination start address. + * \param[in, out] src Pointer to a pointer to the source of data. Pointer-to-pointer + * is used to implement zero-copy buffers. See \ref USBD_ZeroCopy + * for more details on zero-copy concept. + * \param[in] length Number of bytes to be written. + * \return Nothing. + * + */ + void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); + /** + * MSC Read callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a read command. + * + * \param[in] offset Source start address. + * \param[in, out] dst Pointer to a pointer to the source of data. The MSC function drivers + * implemented in stack are written with zero-copy model. Meaning the stack doesn't make an + * extra copy of buffer before writing/reading data from USB hardware FIFO. Hence the + * parameter is pointer to a pointer containing address buffer (uint8_t** dst). + * So that the user application can update the buffer pointer instead of copying data to + * address pointed by the parameter. /note The updated buffer address should be accessible + * by USB DMA master. If user doesn't want to use zero-copy model, then the user should copy + * data to the address pointed by the passed buffer pointer parameter and shouldn't change + * the address value. See \ref USBD_ZeroCopy for more details on zero-copy concept. + * \param[in] length Number of bytes to be read. + * \return Nothing. + * + */ + void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset); + /** + * MSC Verify callback function. + * + * This function is provided by the application software. This function gets called + * when host sends a verify command. The callback function should compare the buffer + * with the destination memory at the requested offset and + * + * \param[in] offset Destination start address. + * \param[in] buf Buffer containing the data sent by the host. + * \param[in] length Number of bytes to verify. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK If data in the buffer matches the data at destination + * \retval ERR_FAILED At least one byte is different. + * + */ + ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t buf[], uint32_t length, uint32_t high_offset); + /** + * Optional callback function to optimize MSC_Write buffer transfer. + * + * This function is provided by the application software. This function gets called + * when host sends SCSI_WRITE10/SCSI_WRITE12 command. The callback function should + * update the \em buff_adr pointer so that the stack transfers the data directly + * to the target buffer. /note The updated buffer address should be accessible + * by USB DMA master. If user doesn't want to use zero-copy model, then the user + * should not update the buffer pointer. See \ref USBD_ZeroCopy for more details + * on zero-copy concept. + * + * \param[in] offset Destination start address. + * \param[in,out] buf Buffer containing the data sent by the host. + * \param[in] length Number of bytes to write. + * \return Nothing. + * + */ + void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); + + /** + * Optional user override-able function to replace the default MSC class handler. + * + * The application software could override the default EP0 class handler with their + * own by providing the handler function address as this data member of the parameter + * structure. Application which like the default handler should set this data member + * to zero before calling the USBD_MSC_API::Init(). + * \n + * \note + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in] data Pointer to the data which will be passed when callback function is called by the stack. + * \param[in] event Type of endpoint event. See \ref USBD_EVENT_T for more details. + * \return The call back should returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success. + * \retval ERR_USBD_UNHANDLED Event is not handled hence pass the event to next in line. + * \retval ERR_USBD_xxx For other error conditions. + * + */ + ErrorCode_t (*MSC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event); + + uint64_t MemorySize64; + +} USBD_MSC_INIT_PARAM_T; + +/** \brief MSC class API functions structure. + * \ingroup USBD_MSC + * + * This module exposes functions which interact directly with USB device controller hardware. + * + */ +typedef struct USBD_MSC_API +{ + /** \fn uint32_t GetMemSize(USBD_MSC_INIT_PARAM_T* param) + * Function to determine the memory required by the MSC function driver module. + * + * This function is called by application layer before calling pUsbApi->msc->Init(), to allocate memory used + * by MSC function driver module. The application should allocate the memory which is accessible by USB + * controller/DMA controller. + * \note Some memory areas are not accessible by all bus masters. + * + * \param[in] param Structure containing MSC function driver module initialization parameters. + * \return Returns the required memory size in bytes. + */ + uint32_t (*GetMemSize)(USBD_MSC_INIT_PARAM_T* param); + + /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param) + * Function to initialize MSC function driver module. + * + * This function is called by application layer to initialize MSC function driver module. + * + * \param[in] hUsb Handle to the USB device stack. + * \param[in, out] param Structure containing MSC function driver module initialization parameters. + * \return Returns \ref ErrorCode_t type to indicate success or error condition. + * \retval LPC_OK On success + * \retval ERR_USBD_BAD_MEM_BUF Memory buffer passed is not 4-byte + * aligned or smaller than required. + * \retval ERR_API_INVALID_PARAM2 Either MSC_Write() or MSC_Read() or + * MSC_Verify() callbacks are not defined. + * \retval ERR_USBD_BAD_INTF_DESC Wrong interface descriptor is passed. + * \retval ERR_USBD_BAD_EP_DESC Wrong endpoint descriptor is passed. + */ + ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param); + +} USBD_MSC_API_T; + +/*----------------------------------------------------------------------------- + * Private functions & structures prototypes + *-----------------------------------------------------------------------------*/ +/** @cond ADVANCED_API */ + +typedef struct _MSC_CTRL_T +{ + /* If it's a USB HS, the max packet is 512, if it's USB FS, + the max packet is 64. Use 512 for both HS and FS. */ + /*ALIGNED(4)*/ uint8_t BulkBuf[USB_HS_MAX_BULK_PACKET]; /* Bulk In/Out Buffer */ + /*ALIGNED(4)*/MSC_CBW CBW; /* Command Block Wrapper */ + /*ALIGNED(4)*/MSC_CSW CSW; /* Command Status Wrapper */ + + USB_CORE_CTRL_T* pUsbCtrl; + + uint64_t Offset; /* R/W Offset */ + uint32_t Length; /* R/W Length */ + uint32_t BulkLen; /* Bulk In/Out Length */ + uint8_t* rx_buf; + + uint8_t BulkStage; /* Bulk Stage */ + uint8_t if_num; /* interface number */ + uint8_t epin_num; /* BULK IN endpoint number */ + uint8_t epout_num; /* BULK OUT endpoint number */ + uint32_t MemOK; /* Memory OK */ + + uint8_t* InquiryStr; + uint32_t BlockCount; + uint32_t BlockSize; + uint64_t MemorySize; + /* user defined functions */ + void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); + void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset); + ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t src[], uint32_t length, uint32_t high_offset); + /* optional call back for MSC_Write optimization */ + void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); + + +}USB_MSC_CTRL_T; + +/** @cond DIRECT_API */ +extern uint32_t mwMSC_GetMemSize(USBD_MSC_INIT_PARAM_T* param); +extern ErrorCode_t mwMSC_init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param); +/** @endcond */ + +/** @endcond */ + + +#endif /* __MSCUSER_H__ */ diff --git a/lpc_chip_15xx/inc/usbd/usbd_rom_api.h b/lpc_chip_15xx/inc/usbd/usbd_rom_api.h new file mode 100644 index 0000000..b00bb52 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd/usbd_rom_api.h @@ -0,0 +1,92 @@ +/*********************************************************************** +* $Id:: mw_usbd_rom_api.h 331 2012-08-09 18:54:34Z usb10131 $ +* +* Project: USB device ROM Stack +* +* Description: +* ROM API Module definitions. +* +*********************************************************************** +* Copyright(C) 2011, NXP Semiconductor +* All rights reserved. +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. +**********************************************************************/ +#ifndef __MW_USBD_ROM_API_H +#define __MW_USBD_ROM_API_H +/** \file + * \brief ROM API for USB device stack. + * + * Definition of functions exported by ROM based USB device stack. + * + */ + +#include "error.h" +#include "usbd.h" +#include "usbd_hw.h" +#include "usbd_core.h" +#include "usbd_mscuser.h" +#include "usbd_dfuuser.h" +#include "usbd_hiduser.h" +#include "usbd_cdcuser.h" + +/** \brief Main USBD API functions structure. + * \ingroup Group_USBD + * + * This structure contains pointer to various USB Device stack's sub-module + * function tables. This structure is used as main entry point to access + * various methods (grouped in sub-modules) exposed by ROM based USB device + * stack. + * + */ +typedef struct USBD_API +{ + const USBD_HW_API_T* hw; /**< Pointer to function table which exposes functions + which interact directly with USB device stack's core + layer.*/ + const USBD_CORE_API_T* core; /**< Pointer to function table which exposes functions + which interact directly with USB device controller + hardware.*/ + const USBD_MSC_API_T* msc; /**< Pointer to function table which exposes functions + provided by MSC function driver module. + */ + const USBD_DFU_API_T* dfu; /**< Pointer to function table which exposes functions + provided by DFU function driver module. + */ + const USBD_HID_API_T* hid; /**< Pointer to function table which exposes functions + provided by HID function driver module. + */ + const USBD_CDC_API_T* cdc; /**< Pointer to function table which exposes functions + provided by CDC-ACM function driver module. + */ + const uint32_t* reserved6; /**< Reserved for future function driver module. + */ + const uint32_t version; /**< Version identifier of USB ROM stack. The version is + defined as 0x0CHDMhCC where each nibble represents version + number of the corresponding component. + CC - 7:0 - 8bit core version number + h - 11:8 - 4bit hardware interface version number + M - 15:12 - 4bit MSC class module version number + D - 19:16 - 4bit DFU class module version number + H - 23:20 - 4bit HID class module version number + C - 27:24 - 4bit CDC class module version number + H - 31:28 - 4bit reserved + */ + +} USBD_API_T; + +/* Applications using USBD ROM API should define this instance. The pointer should be assigned a value computed based on chip definitions. */ +extern const USBD_API_T* g_pUsbApi; +#define USBD_API g_pUsbApi + +#endif /*__MW_USBD_ROM_API_H*/ + diff --git a/lpc_chip_15xx/inc/usbd_15xx.h b/lpc_chip_15xx/inc/usbd_15xx.h new file mode 100644 index 0000000..c7d20f1 --- /dev/null +++ b/lpc_chip_15xx/inc/usbd_15xx.h @@ -0,0 +1,72 @@ +/* + * @brief LPC15xx USB device register block + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __USBD_15XX_H_ +#define __USBD_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup USBD_15XX CHIP: LPC15xx USB Device driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief USB device register block structure + */ +typedef struct { /*!< USB Structure */ + __IO uint32_t DEVCMDSTAT; /*!< USB Device Command/Status register */ + __IO uint32_t INFO; /*!< USB Info register */ + __IO uint32_t EPLISTSTART; /*!< USB EP Command/Status List start address */ + __IO uint32_t DATABUFSTART; /*!< USB Data buffer start address */ + __IO uint32_t LPM; /*!< Link Power Management register */ + __IO uint32_t EPSKIP; /*!< USB Endpoint skip */ + __IO uint32_t EPINUSE; /*!< USB Endpoint Buffer in use */ + __IO uint32_t EPBUFCFG; /*!< USB Endpoint Buffer Configuration register */ + __IO uint32_t INTSTAT; /*!< USB interrupt status register */ + __IO uint32_t INTEN; /*!< USB interrupt enable register */ + __IO uint32_t INTSETSTAT; /*!< USB set interrupt status register */ + __IO uint32_t INTROUTING; /*!< USB interrupt routing register */ + __I uint32_t RESERVED0[1]; + __I uint32_t EPTOGGLE; /*!< USB Endpoint toggle register */ +} LPC_USB_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_15XX_H_ */ diff --git a/lpc_chip_15xx/inc/wwdt_15xx.h b/lpc_chip_15xx/inc/wwdt_15xx.h new file mode 100644 index 0000000..a48f77a --- /dev/null +++ b/lpc_chip_15xx/inc/wwdt_15xx.h @@ -0,0 +1,222 @@ +/* + * @brief LPC15xx WWDT chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __WWDT_15XX_H_ +#define __WWDT_15XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup WWDT_15XX CHIP: LPC15xx Windowed Watchdog driver + * @ingroup CHIP_15XX_Drivers + * @{ + */ + +/** + * @brief Windowed Watchdog register block structure + */ +typedef struct { /*!< WWDT Structure */ + __IO uint32_t MOD; /*!< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */ + __IO uint32_t TC; /*!< Watchdog timer constant register. This register determines the time-out value. */ + __O uint32_t FEED; /*!< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC. */ + __I uint32_t TV; /*!< Watchdog timer value register. This register reads out the current value of the Watchdog timer. */ + __IO uint32_t RESERVED; + __IO uint32_t WARNINT; /*!< Watchdog warning interrupt register. This register contains the Watchdog warning interrupt compare value. */ + __IO uint32_t WINDOW; /*!< Watchdog timer window register. This register contains the Watchdog window value. */ +} LPC_WWDT_T; + +/** + * @brief Watchdog Mode register definitions + */ +/** Watchdog Mode Bitmask */ +#define WWDT_WDMOD_BITMASK ((uint32_t) 0x1F) +/** WWDT interrupt enable bit */ +#define WWDT_WDMOD_WDEN ((uint32_t) (1 << 0)) +/** WWDT interrupt enable bit */ +#define WWDT_WDMOD_WDRESET ((uint32_t) (1 << 1)) +/** WWDT time out flag bit */ +#define WWDT_WDMOD_WDTOF ((uint32_t) (1 << 2)) +/** WDT Time Out flag bit */ +#define WWDT_WDMOD_WDINT ((uint32_t) (1 << 3)) +/** WWDT Protect flag bit */ +#define WWDT_WDMOD_WDPROTECT ((uint32_t) (1 << 4)) +/** WWDT lock bit */ +#define WWDT_WDMOD_LOCK ((uint32_t) (1 << 5)) + +/** + * @brief Initialize the Watchdog timer + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return None + */ +void Chip_WWDT_Init(LPC_WWDT_T *pWWDT); + +/** + * @brief Shutdown the Watchdog timer + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return None + */ +STATIC INLINE void Chip_WWDT_DeInit(LPC_WWDT_T *pWWDT) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_WDT); +} + +/** + * @brief Set WDT timeout constant value used for feed + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param timeout : WDT timeout in ticks, between WWDT_TICKS_MIN and WWDT_TICKS_MAX + * @return none + */ +STATIC INLINE void Chip_WWDT_SetTimeOut(LPC_WWDT_T *pWWDT, uint32_t timeout) +{ + pWWDT->TC = timeout; +} + +/** + * @brief Feed watchdog timer + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return None + * @note If this function isn't called, a watchdog timer warning will occur. + * After the warning, a timeout will occur if a feed has happened. + */ +STATIC INLINE void Chip_WWDT_Feed(LPC_WWDT_T *pWWDT) +{ + pWWDT->FEED = 0xAA; + pWWDT->FEED = 0x55; +} + +/** + * @brief Set WWDT warning interrupt + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param timeout : WDT warning in ticks, between 0 and 1023 + * @return None + * @note This is the number of ticks after the watchdog interrupt that the + * warning interrupt will be generated. + */ +STATIC INLINE void Chip_WWDT_SetWarning(LPC_WWDT_T *pWWDT, uint32_t timeout) +{ + pWWDT->WARNINT = timeout; +} + +/** + * @brief Set WWDT window time + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param timeout : WDT timeout in ticks, between WWDT_TICKS_MIN and WWDT_TICKS_MAX + * @return None + * @note The watchdog timer must be fed between the timeout from the Chip_WWDT_SetTimeOut() + * function and this function, with this function defining the last tick before the + * watchdog window interrupt occurs. + */ +STATIC INLINE void Chip_WWDT_SetWindow(LPC_WWDT_T *pWWDT, uint32_t timeout) +{ + pWWDT->WINDOW = timeout; +} + +/** + * @brief Enable watchdog timer options + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param options : An or'ed set of options of values + * WWDT_WDMOD_WDEN, WWDT_WDMOD_WDRESET, and WWDT_WDMOD_WDPROTECT + * @return None + * @note You can enable more than one option at once (ie, WWDT_WDMOD_WDRESET | + * WWDT_WDMOD_WDPROTECT), but use the WWDT_WDMOD_WDEN after all other options + * are set (or unset) with no other options. If WWDT_WDMOD_LOCK is used, it cannot + * be unset. + */ +STATIC INLINE void Chip_WWDT_SetOption(LPC_WWDT_T *pWWDT, uint32_t options) +{ + pWWDT->MOD |= options; +} + +/** + * @brief Disable/clear watchdog timer options + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param options : An or'ed set of options of values + * WWDT_WDMOD_WDEN, WWDT_WDMOD_WDRESET, and WWDT_WDMOD_WDPROTECT + * @return None + * @note You can disable more than one option at once (ie, WWDT_WDMOD_WDRESET | + * WWDT_WDMOD_WDTOF). + */ +STATIC INLINE void Chip_WWDT_UnsetOption(LPC_WWDT_T *pWWDT, uint32_t options) +{ + pWWDT->MOD &= (~options) & WWDT_WDMOD_BITMASK; +} + +/** + * @brief Enable WWDT activity + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return None + */ +STATIC INLINE void Chip_WWDT_Start(LPC_WWDT_T *pWWDT) +{ + Chip_WWDT_SetOption(pWWDT, WWDT_WDMOD_WDEN); + Chip_WWDT_Feed(pWWDT); +} + +/** + * @brief Read WWDT status flag + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return Watchdog status, an Or'ed value of WWDT_WDMOD_* + */ +STATIC INLINE uint32_t Chip_WWDT_GetStatus(LPC_WWDT_T *pWWDT) +{ + return pWWDT->MOD; +} + +/** + * @brief Clear WWDT interrupt status flags + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @param status : Or'ed value of status flag(s) that you want to clear, should be: + * - WWDT_WDMOD_WDTOF: Clear watchdog timeout flag + * - WWDT_WDMOD_WDINT: Clear watchdog warning flag + * @return None + */ +void Chip_WWDT_ClearStatusFlag(LPC_WWDT_T *pWWDT, uint32_t status); + +/** + * @brief Get the current value of WDT + * @param pWWDT : The base of WatchDog Timer peripheral on the chip + * @return current value of WDT + */ +STATIC INLINE uint32_t Chip_WWDT_GetCurrentCount(LPC_WWDT_T *pWWDT) +{ + return pWWDT->TV; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __WWDT_15XX_H_ */ diff --git a/lpc_chip_15xx/src/acmp_15xx.c b/lpc_chip_15xx/src/acmp_15xx.c new file mode 100644 index 0000000..96ffc37 --- /dev/null +++ b/lpc_chip_15xx/src/acmp_15xx.c @@ -0,0 +1,146 @@ +/* + * @brief LPC15xx Analog comparator driver + * + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initializes the ACMP */ +void Chip_ACMP_Init(LPC_CMP_T *pACMP) +{ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ACMP0_PD | SYSCTL_POWERDOWN_ACMP1_PD | + SYSCTL_POWERDOWN_ACMP2_PD | SYSCTL_POWERDOWN_ACMP3_PD); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ACMP); + Chip_SYSCTL_PeriphReset(RESET_ACMP); +} + +/* De-initializes the ACMP */ +void Chip_ACMP_Deinit(LPC_CMP_T *pACMP) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ACMP); + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ACMP0_PD | SYSCTL_POWERDOWN_ACMP1_PD | + SYSCTL_POWERDOWN_ACMP2_PD | SYSCTL_POWERDOWN_ACMP3_PD); +} + +/*Sets up ACMP edge selection */ +void Chip_ACMP_SetIntEdgeSelection(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_EDGESEL_T edgeSel) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTEDGE_MASK; + + pACMP->ACMP[index].CMP = reg | (uint32_t) edgeSel; +} + +/*Selects positive voltage input */ +void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_POS_INPUT_T Posinput) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_COMPVPSEL_MASK; + + /* Select positive input */ + pACMP->ACMP[index].CMP = reg | (uint32_t) Posinput; +} + +/*Selects negative voltage input */ +void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_NEG_INPUT_T Neginput) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_COMPVMSEL_MASK; + + /* Select negative input */ + pACMP->ACMP[index].CMP = reg | (uint32_t) Neginput; +} + +/*Selects hysteresis level */ +void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_HYS_T hys) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_HYSTERESIS_MASK; + + pACMP->ACMP[index].CMP = reg | (uint32_t) hys; +} + +/*Helper function for setting up ACMP voltage settings */ +void Chip_ACMP_SetupACMPRefs(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_POS_INPUT_T Posinput, + CHIP_ACMP_NEG_INPUT_T Neginput, CHIP_ACMP_HYS_T hys) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~(ACMP_HYSTERESIS_MASK | + ACMP_COMPVMSEL_MASK | ACMP_COMPVPSEL_MASK); + + pACMP->ACMP[index].CMP = reg | (uint32_t) Posinput | (uint32_t) Neginput | (uint32_t) hys; +} + +/*Helper function for setting up ACMP interrupt settings */ +void Chip_ACMP_SetupACMPInt(LPC_CMP_T *pACMP, uint8_t index, bool level, + bool invert, CHIP_ACMP_EDGESEL_T edgeSel) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~(ACMP_INTPOL_BIT | + ACMP_INTTYPE_BIT | ACMP_INTEDGE_MASK); + /* For Level triggered interrupt, invert sets the polarity + For edge triggered interrupt edgeSel sets the edge type */ + if (level) { + reg |= ACMP_INTTYPE_BIT; + if (invert) { + reg |= ACMP_INTPOL_BIT; + } + } + else { + reg |= (uint32_t) edgeSel; + } + + pACMP->ACMP[index].CMP = reg; +} + +/*Sets up voltage ladder */ +void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint8_t index, uint32_t ladsel, bool ladrefVDDCMP) +{ + /* Make sure interrupt flag is not set during read OR/AND and write operation */ + uint32_t reg = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~(ACMP_LADSEL_MASK | ACMP_LADREF_BIT); + + /* Setup voltage ladder and ladder reference */ + if (!ladrefVDDCMP) { + reg |= ACMP_LADREF_BIT; + } + pACMP->ACMP[index].CMP = reg | (ladsel << 24); +} diff --git a/lpc_chip_15xx/src/adc_15xx.c b/lpc_chip_15xx/src/adc_15xx.c new file mode 100644 index 0000000..213099f --- /dev/null +++ b/lpc_chip_15xx/src/adc_15xx.c @@ -0,0 +1,229 @@ +/* + * @brief LPC15xx ADC driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Set ADC interrupt bits (safe) */ +void Chip_ADC_SetIntBits(LPC_ADC_T *pADC, uint32_t intMask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pADC->INTEN & 0x07FFFFFF; + + pADC->INTEN = temp | intMask; +} + +/* Clear ADC interrupt bits (safe) */ +void Chip_ADC_ClearIntBits(LPC_ADC_T *pADC, uint32_t intMask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pADC->INTEN & 0x07FFFFFF; + + pADC->INTEN = temp & ~intMask; +} + +/* Set ADC threshold selection bits (safe) */ +void Chip_ADC_SetTHRSELBits(LPC_ADC_T *pADC, uint32_t mask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pADC->CHAN_THRSEL & 0x00000FFF; + + pADC->CHAN_THRSEL = temp | mask; +} + +/* Clear ADC threshold selection bits (safe) */ +void Chip_ADC_ClearTHRSELBits(LPC_ADC_T *pADC, uint32_t mask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pADC->CHAN_THRSEL & 0x00000FFF; + + pADC->CHAN_THRSEL = temp & ~mask; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the ADC peripheral */ +void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags) +{ + /* Power up ADC and enable ADC base clock */ + if (pADC == LPC_ADC0) { + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC0_PD); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC0); + Chip_SYSCTL_PeriphReset(RESET_ADC0); + } + else { + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC1_PD); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC1); + Chip_SYSCTL_PeriphReset(RESET_ADC1); + } + + /* Disable ADC interrupts */ + pADC->INTEN = 0; + + /* Set ADC control options */ + pADC->CTRL = flags; +} + +/* Shutdown ADC */ +void Chip_ADC_DeInit(LPC_ADC_T *pADC) +{ + pADC->INTEN = 0; + pADC->CTRL = 0; + + /* Stop ADC clock and then power down ADC */ + if (pADC == LPC_ADC0) { + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC0); + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC0_PD); + } + else { + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC1); + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC1_PD); + } +} + +/* Set ADC clock rate */ +void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate) +{ + uint32_t div; + + /* Get ADC clock source to determine base ADC rate. IN sychronous mode, + the ADC base clock comes from the system clock. In ASYNC mode, it + comes from the ASYNC ADC clock and this function doesn't work. */ + div = Chip_Clock_GetSystemClockRate() / rate; + if (div == 0) { + div = 1; + } + + Chip_ADC_SetDivider(pADC, (uint8_t) div - 1); +} + +/* Start ADC calibration */ +void Chip_ADC_StartCalibration(LPC_ADC_T *pADC) +{ + /* Set calibration mode */ + pADC->CTRL |= ADC_CR_CALMODEBIT; + + /* Clear ASYNC bit */ + pADC->CTRL &= ~ADC_CR_ASYNMODE; + + /* Setup ADC for about 500KHz (per UM) */ + Chip_ADC_SetClockRate(pADC, 500000); + + /* Clearn low power bit */ + pADC->CTRL &= ~ADC_CR_LPWRMODEBIT; + + /* Calibration is only complete when ADC_CR_CALMODEBIT bit has cleared */ +} + +/* Helper function for safely setting ADC sequencer register bits */ +void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits) +{ + uint32_t temp; + + /* Read sequencer register and mask off bits 20..25 */ + temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20); + + /* OR in passed bits */ + pADC->SEQ_CTRL[seqIndex] = temp | bits; +} + +/* Helper function for safely clearing ADC sequencer register bits */ +void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits) +{ + uint32_t temp; + + /* Read sequencer register and mask off bits 20..25 */ + temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20); + + /* OR in passed bits */ + pADC->SEQ_CTRL[seqIndex] = temp & ~bits; +} + +/* Enable interrupts in ADC (sequencers A/B and overrun) */ +void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask) +{ + Chip_ADC_SetIntBits(pADC, intMask); +} + +/* Disable interrupts in ADC (sequencers A/B and overrun) */ +void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask) +{ + Chip_ADC_ClearIntBits(pADC, intMask); +} + +/* Enable a threshold event interrupt in ADC */ +void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt) +{ + int shiftIndex = 3 + (ch * 2); + + /* Clear current bits first */ + Chip_ADC_ClearIntBits(pADC, (ADC_INTEN_CMP_MASK << shiftIndex)); + + /* Set new threshold interrupt type */ + Chip_ADC_SetIntBits(pADC, ((uint32_t) thInt << shiftIndex)); +} + +/* Select threshold 0 values for comparison for selected channels */ +void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels) +{ + Chip_ADC_ClearTHRSELBits(pADC, channels); +} + +/* Select threshold 1 value for comparison for selected channels */ +void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels) +{ + Chip_ADC_SetTHRSELBits(pADC, channels); +} diff --git a/lpc_chip_15xx/src/chip_15xx.c b/lpc_chip_15xx/src/chip_15xx.c new file mode 100644 index 0000000..0ca75dd --- /dev/null +++ b/lpc_chip_15xx/src/chip_15xx.c @@ -0,0 +1,85 @@ +/* + * @brief LPC15xx Miscellaneous chip specific functions + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/* System Clock Frequency (Core Clock) */ +uint32_t SystemCoreClock; + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Update system core clock rate, should be called if the system has + a clock rate change */ +void SystemCoreClockUpdate(void) +{ + /* CPU core speed */ + SystemCoreClock = Chip_Clock_GetSystemClockRate(); +} + +void Chip_USB_Init(void) +{ + /* Set USB PLL input to main oscillator */ + Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_MAINOSC); + /* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz + MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz + FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */ + Chip_Clock_SetupUSBPLL(3, 1); + + /* Powerup USB PLL */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD); + + /* Wait for PLL to lock */ + while (!Chip_Clock_IsUSBPLLLocked()) {} + + /* enable USB main clock */ + Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1); + /* Enable AHB clock to the USB block. */ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB); + /* power UP USB Phy */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPHY_PD); + /* Reset USB block */ + Chip_SYSCTL_PeriphReset(RESET_USB); +} diff --git a/lpc_chip_15xx/src/clock_15xx.c b/lpc_chip_15xx/src/clock_15xx.c new file mode 100644 index 0000000..81b34b2 --- /dev/null +++ b/lpc_chip_15xx/src/clock_15xx.c @@ -0,0 +1,403 @@ +/* + * @brief LPC15XX System clock control functions + * + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Compute a PLL frequency */ +STATIC uint32_t Chip_Clock_GetPLLFreq(uint32_t PLLReg, uint32_t inputRate) +{ + uint32_t msel = ((PLLReg & 0x3F) + 1); + + return inputRate * msel; +} + +/* Return a PLL input (common) */ +STATIC uint32_t Chip_Clock_GetPLLInClockRate(uint32_t reg) +{ + uint32_t clkRate; + + switch ((CHIP_SYSCTL_PLLCLKSRC_T) (reg & 0x3)) { + case SYSCTL_PLLCLKSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCTL_PLLCLKSRC_MAINOSC: + clkRate = Chip_Clock_GetMainOscRate(); + break; + + default: + clkRate = 0; + } + + return clkRate; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Return System PLL input clock rate */ +uint32_t Chip_Clock_GetSystemPLLInClockRate(void) +{ + return Chip_Clock_GetPLLInClockRate(LPC_SYSCTL->SYSPLLCLKSEL); +} + +/* Return System PLL output clock rate */ +uint32_t Chip_Clock_GetSystemPLLOutClockRate(void) +{ + return Chip_Clock_GetPLLFreq(LPC_SYSCTL->SYSPLLCTRL, + Chip_Clock_GetSystemPLLInClockRate()); +} + +/* Return USB PLL input clock rate */ +uint32_t Chip_Clock_GetUSBPLLInClockRate(void) +{ + return Chip_Clock_GetPLLInClockRate(LPC_SYSCTL->USBPLLCLKSEL); +} + +/* Return USB PLL output clock rate */ +uint32_t Chip_Clock_GetUSBPLLOutClockRate(void) +{ + return Chip_Clock_GetPLLFreq(LPC_SYSCTL->USBPLLCTRL, + Chip_Clock_GetUSBPLLInClockRate()); +} + +/* Return SCT PLL input clock rate */ +uint32_t Chip_Clock_GetSCTPLLInClockRate(void) +{ + return Chip_Clock_GetPLLInClockRate(LPC_SYSCTL->SCTPLLCLKSEL); +} + +/* Return SCT PLL output clock rate */ +uint32_t Chip_Clock_GetSCTPLLOutClockRate(void) +{ + return Chip_Clock_GetPLLFreq(LPC_SYSCTL->SCTPLLCTRL, + Chip_Clock_GetSCTPLLInClockRate()); +} + +/* Return main A clock rate */ +uint32_t Chip_Clock_GetMain_A_ClockRate(void) +{ + uint32_t clkRate = 0; + + switch (Chip_Clock_GetMain_A_ClockSource()) { + case SYSCTL_MAIN_A_CLKSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCTL_MAIN_A_CLKSRCA_MAINOSC: + clkRate = Chip_Clock_GetMainOscRate(); + break; + + case SYSCTL_MAIN_A_CLKSRCA_WDTOSC: + clkRate = Chip_Clock_GetWDTOSCRate(); + break; + + default: + clkRate = 0; + break; + } + + return clkRate; +} + +/* Return main B clock rate */ +uint32_t Chip_Clock_GetMain_B_ClockRate(void) +{ + uint32_t clkRate = 0; + + switch (Chip_Clock_GetMain_B_ClockSource()) { + case SYSCTL_MAIN_B_CLKSRC_MAINCLKSELA: + clkRate = Chip_Clock_GetMain_A_ClockRate(); + break; + + case SYSCTL_MAIN_B_CLKSRC_SYSPLLIN: + clkRate = Chip_Clock_GetSystemPLLInClockRate(); + break; + + case SYSCTL_MAIN_B_CLKSRC_SYSPLLOUT: + clkRate = Chip_Clock_GetSystemPLLOutClockRate(); + break; + + case SYSCTL_MAIN_B_CLKSRC_RTC: + clkRate = Chip_Clock_GetRTCOscRate(); + break; + } + + return clkRate; +} + +/* Set main system clock source */ +void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src) +{ + uint32_t clkSrc = (uint32_t) src; + + if (clkSrc >= 4) { + /* Main B source only, not using main A */ + Chip_Clock_SetMain_B_ClockSource((CHIP_SYSCTL_MAIN_B_CLKSRC_T) (clkSrc - 4)); + } + else { + /* Select main A clock source and set main B source to use main A */ + Chip_Clock_SetMain_A_ClockSource((CHIP_SYSCTL_MAIN_A_CLKSRC_T) clkSrc); + Chip_Clock_SetMain_B_ClockSource(SYSCTL_MAIN_B_CLKSRC_MAINCLKSELA); + } +} + +/* Returns the main clock source */ +CHIP_SYSCTL_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void) +{ + CHIP_SYSCTL_MAIN_B_CLKSRC_T srcB; + uint32_t clkSrc; + + /* Get main B clock source */ + srcB = Chip_Clock_GetMain_B_ClockSource(); + if (srcB == SYSCTL_MAIN_B_CLKSRC_MAINCLKSELA) { + /* Using source A, so return source A */ + clkSrc = (uint32_t) Chip_Clock_GetMain_A_ClockSource(); + } + else { + /* Using source B */ + clkSrc = 4 + (uint32_t) srcB; + } + + return (CHIP_SYSCTL_MAINCLKSRC_T) clkSrc; +} + +/* Return main clock rate */ +uint32_t Chip_Clock_GetMainClockRate(void) +{ + uint32_t clkRate; + + if (Chip_Clock_GetMain_B_ClockSource() == SYSCTL_MAIN_B_CLKSRC_MAINCLKSELA) { + /* Return main A clock rate */ + clkRate = Chip_Clock_GetMain_A_ClockRate(); + } + else { + /* Return main B clock rate */ + clkRate = Chip_Clock_GetMain_B_ClockRate(); + } + + return clkRate; +} + +/* Return ADC asynchronous clock rate */ +uint32_t Chip_Clock_GetADCASYNCRate(void) +{ + uint32_t clkRate = 0; + + switch (Chip_Clock_GetADCASYNCSource()) { + case SYSCTL_ADCASYNCCLKSRC_IRC: + clkRate = Chip_Clock_GetIntOscRate(); + break; + + case SYSCTL_ADCASYNCCLKSRC_SYSPLLOUT: + clkRate = Chip_Clock_GetSystemPLLOutClockRate(); + break; + + case SYSCTL_ADCASYNCCLKSRC_USBPLLOUT: + clkRate = Chip_Clock_GetUSBPLLOutClockRate(); + break; + + case SYSCTL_ADCASYNCCLKSRC_SCTPLLOUT: + clkRate = Chip_Clock_GetSCTPLLOutClockRate(); + break; + } + + return clkRate; +} + +/** + * @brief Set CLKOUT clock source and divider + * @param src : Clock source for CLKOUT + * @param div : divider for CLKOUT clock + * @return Nothing + * @note Use 0 to disable, or a divider value of 1 to 255. The CLKOUT clock + * rate is the clock source divided by the divider. This function will + * also toggle the clock source update register to update the clock + * source. + */ +void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div) +{ + uint32_t srcClk = (uint32_t) src; + + /* Use a clock A source? */ + if (src >= 4) { + /* Not using a CLKOUT A source */ + LPC_SYSCTL->CLKOUTSEL[1] = srcClk - 4; + } + else { + /* Using a clock A source, select A and then switch B to A */ + LPC_SYSCTL->CLKOUTSEL[0] = srcClk; + LPC_SYSCTL->CLKOUTSEL[1] = 0; + } + + LPC_SYSCTL->CLKOUTDIV = div; +} + +/* Enable a system or peripheral clock */ +void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk) +{ + uint32_t clkEnab = (uint32_t) clk; + + if (clkEnab >= 32) { + LPC_SYSCTL->SYSAHBCLKCTRL[1] |= (1 << (clkEnab - 32)); + } + else { + LPC_SYSCTL->SYSAHBCLKCTRL[0] |= (1 << clkEnab); + } +} + +/* Disable a system or peripheral clock */ +void Chip_Clock_DisablePeriphClock(CHIP_SYSCTL_CLOCK_T clk) +{ + uint32_t clkEnab = (uint32_t) clk; + + if (clkEnab >= 32) { + LPC_SYSCTL->SYSAHBCLKCTRL[1] &= ~(1 << (clkEnab - 32)); + } + else { + LPC_SYSCTL->SYSAHBCLKCTRL[0] &= ~(1 << clkEnab); + } +} + +/* Returns the system tick rate as used with the system tick divider */ +uint32_t Chip_Clock_GetSysTickClockRate(void) +{ + uint32_t sysRate, div; + + div = Chip_Clock_GetSysTickClockDiv(); + + /* If divider is 0, the system tick clock is disabled */ + if (div == 0) { + sysRate = 0; + } + else { + sysRate = Chip_Clock_GetMainClockRate() / div; + } + + return sysRate; +} + +/* Get UART base rate */ +uint32_t Chip_Clock_GetUARTBaseClockRate(void) +{ + uint64_t inclk; + uint32_t div; + + div = (uint32_t) Chip_Clock_GetUARTFRGDivider(); + if (div == 0) { + /* Divider is 0 so UART clock is disabled */ + inclk = 0; + } + else { + uint32_t mult, divmult; + + /* Input clock into FRG block is the divided main system clock */ + inclk = (uint64_t) (Chip_Clock_GetMainClockRate() / div); + + divmult = LPC_SYSCTL->FRGCTRL & 0xFFFF; + if ((divmult & 0xFF) == 0xFF) { + /* Fractional part is enabled, get multiplier */ + mult = (divmult >> 8) & 0xFF; + + /* Get fractional error */ + inclk = (inclk * 256) / (uint64_t) (256 + mult); + } + } + + return (uint32_t) inclk; +} + +/* Set UART base rate */ +uint32_t Chip_Clock_SetUARTBaseClockRate(uint32_t rate, bool fEnable) +{ + uint32_t div, inclk; + + /* Input clock into FRG block is the main system cloock */ + inclk = Chip_Clock_GetMainClockRate(); + + /* Get integer divider for coarse rate */ + div = inclk / rate; + if (div == 0) { + div = 1; + } + + /* Approximated rate with only integer divider */ + Chip_Clock_SetUARTFRGDivider((uint8_t) div); + + if (fEnable) { + uint32_t err; + uint64_t uart_fra_multiplier; + + err = inclk - (rate * div); + uart_fra_multiplier = ((uint64_t) err * 256) / (uint64_t) (rate * div); + + /* Enable fractional divider and set multiplier */ + LPC_SYSCTL->FRGCTRL = 0xFF | ((uart_fra_multiplier & 0xFF) << 8); + } + else { + /* Disable fractional generator and use integer divider only */ + LPC_SYSCTL->FRGCTRL = 0; + } + + return Chip_Clock_GetUARTBaseClockRate(); +} + +/* Bypass System Oscillator and set oscillator frequency range */ +void Chip_Clock_SetPLLBypass(bool bypass, bool highfr) +{ + uint32_t ctrl = 0; + + if (bypass) { + ctrl |= (1 << 0); + } + if (highfr) { + ctrl |= (1 << 1); + } + + LPC_SYSCTL->SYSOSCCTRL = ctrl; +} + +/* Return system clock rate */ +uint32_t Chip_Clock_GetSystemClockRate(void) +{ + /* No point in checking for divide by 0 */ + return Chip_Clock_GetMainClockRate() / LPC_SYSCTL->SYSAHBCLKDIV; +} diff --git a/lpc_chip_15xx/src/crc_15xx.c b/lpc_chip_15xx/src/crc_15xx.c new file mode 100644 index 0000000..5b23c0b --- /dev/null +++ b/lpc_chip_15xx/src/crc_15xx.c @@ -0,0 +1,118 @@ +/* + * @brief LPC15xx Cyclic Redundancy Check (CRC) Engine driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize CRC engine */ +void Chip_CRC_Init(void) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CRC); + Chip_SYSCTL_PeriphReset(RESET_CRC); +} + +/* De-initialize CRC engine */ +void Chip_CRC_Deinit(void) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_CRC); +} + +/* Sets up the CRC engine with defaults based on the polynomial to be used */ +void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly) +{ + switch (poly) { + case CRC_POLY_CRC16: + Chip_CRC_UseCRC16(); + break; + + case CRC_POLY_CRC32: + Chip_CRC_UseCRC32(); + break; + + case CRC_POLY_CCITT: + default: + Chip_CRC_UseCCITT(); + break; + } +} + +/* configure CRC engine and compute CCITT checksum from 8-bit data */ +uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes) +{ + Chip_CRC_UseCCITT(); + while (bytes > 0) { + Chip_CRC_Write8(*data); + data++; + bytes--; + } + + return Chip_CRC_Sum(); +} + +/* Convenience function for computing a standard CRC16 checksum from 16-bit data block */ +uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords) +{ + Chip_CRC_UseCRC16(); + while (hwords > 0) { + Chip_CRC_Write16(*data); + data++; + hwords--; + } + + return Chip_CRC_Sum(); +} + +/* Convenience function for computing a standard CRC32 checksum from 32-bit data block */ +uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words) +{ + Chip_CRC_UseCRC32(); + while (words > 0) { + Chip_CRC_Write32(*data); + data++; + words--; + } + + return Chip_CRC_Sum(); +} diff --git a/lpc_chip_15xx/src/dac_15xx.c b/lpc_chip_15xx/src/dac_15xx.c new file mode 100644 index 0000000..08781b8 --- /dev/null +++ b/lpc_chip_15xx/src/dac_15xx.c @@ -0,0 +1,62 @@ +/* + * @brief LPC15xx D/A conversion driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the DAC peripheral */ +void Chip_DAC_Init(LPC_DAC_T *pDAC) +{ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_DAC_PD); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_DAC); +} + +/* Shutdown DAC peripheral */ +void Chip_DAC_DeInit(LPC_DAC_T *pDAC) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_DAC); + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_DAC_PD); +} diff --git a/lpc_chip_15xx/src/dma_15xx.c b/lpc_chip_15xx/src/dma_15xx.c new file mode 100644 index 0000000..f72f9e9 --- /dev/null +++ b/lpc_chip_15xx/src/dma_15xx.c @@ -0,0 +1,115 @@ +/* + * @brief LPC15xx DMA chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase() + function if a DMA SRAM table is needed. This table is correctly aligned for + the DMA controller. */ +#if defined(__CC_ARM) +/* Keil alignement to 512 bytes */ +__align(512) DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL]; +#endif /* defined (__CC_ARM) */ + +/* IAR support */ +#if defined(__ICCARM__) +/* IAR EWARM alignement to 512 bytes */ +#pragma data_alignment=512 +DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL]; +#endif /* defined (__ICCARM__) */ + +#if defined( __GNUC__ ) +/* GNU alignement to 512 bytes */ +DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL] __attribute__ ((aligned(512))); +#endif /* defined (__GNUC__) */ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set DMA transfer register interrupt bits (safe) */ +void Chip_DMA_SetTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pDMA->DMACH[ch].XFERCFG & ~0xFC000CC0; + + pDMA->DMACH[ch].XFERCFG = temp | mask; +} + +/* Clear DMA transfer register interrupt bits (safe) */ +void Chip_DMA_ClearTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask) +{ + uint32_t temp; + + /* Read and write values may not be the same, write 0 to + undefined bits */ + temp = pDMA->DMACH[ch].XFERCFG & ~0xFC000CC0; + + pDMA->DMACH[ch].XFERCFG = temp & ~mask; +} + +/* Update the transfer size in an existing DMA channel transfer configuration */ +void Chip_DMA_SetupChannelTransferSize(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t trans) +{ + Chip_DMA_ClearTranBits(pDMA, ch, (0x3FF << 16)); + Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_XFERCOUNT(trans)); +} + +/* Sets up a DMA channel with the passed DMA transfer descriptor */ +bool Chip_DMA_SetupTranChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch, DMA_CHDESC_T *desc) +{ + bool good = false; + DMA_CHDESC_T *pDesc = (DMA_CHDESC_T *) pDMA->SRAMBASE; + + if ((Chip_DMA_GetActiveChannels(pDMA) & (1 << ch)) == 0) { + /* Channel is not active, so update the descriptor */ + pDesc[ch] = *desc; + + good = true; + } + + return good; +} diff --git a/lpc_chip_15xx/src/eeprom.c b/lpc_chip_15xx/src/eeprom.c new file mode 100644 index 0000000..ba9b51b --- /dev/null +++ b/lpc_chip_15xx/src/eeprom.c @@ -0,0 +1,79 @@ +/* + * @brief Common EEPROM support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" +#include "eeprom.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Write data to EEPROM */ +uint8_t Chip_EEPROM_Write(uint32_t dstAdd, uint8_t *ptr, uint32_t byteswrt) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_EEPROM_WRITE; + command[1] = dstAdd; + command[2] = (uint32_t) ptr; + command[3] = byteswrt; + command[4] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} + +/* Read data from EEPROM */ +uint8_t Chip_EEPROM_Read(uint32_t srcAdd, uint8_t *ptr, uint32_t bytesrd) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_EEPROM_READ; + command[1] = srcAdd; + command[2] = (uint32_t) ptr; + command[3] = bytesrd; + command[4] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} diff --git a/lpc_chip_15xx/src/gpio_15xx.c b/lpc_chip_15xx/src/gpio_15xx.c new file mode 100644 index 0000000..4205037 --- /dev/null +++ b/lpc_chip_15xx/src/gpio_15xx.c @@ -0,0 +1,112 @@ +/* + * @brief LPC15xx GPIO driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize GPIO block */ +void Chip_GPIO_Init(LPC_GPIO_T *pGPIO) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO0); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO1); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO2); + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MUX); + + Chip_SYSCTL_PeriphReset(RESET_MUX); +} + +/* De-Initialize GPIO block */ +void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO) +{ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO0); + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO1); + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_GPIO2); + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MUX); +} + +/* Set a GPIO direction */ +void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit, bool setting) +{ + if (setting) { + pGPIO->DIR[port] |= 1UL << bit; + } + else { + pGPIO->DIR[port] &= ~(1UL << bit); + } +} + +/* Set Direction for a GPIO port */ +void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out) +{ + if (out) { + pGPIO->DIR[portNum] |= bitValue; + } + else { + pGPIO->DIR[portNum] &= ~bitValue; + } +} + +/* Set GPIO direction for a single GPIO pin */ +void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output) +{ + if (output) { + Chip_GPIO_SetPinDIROutput(pGPIO, port, pin); + } + else { + Chip_GPIO_SetPinDIRInput(pGPIO, port, pin); + } +} + +/* Set GPIO direction for a all selected GPIO pins to an input or output */ +void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pinMask, bool outSet) +{ + if (outSet) { + Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask); + } + else { + Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask); + } +} diff --git a/lpc_chip_15xx/src/i2c_common_15xx.c b/lpc_chip_15xx/src/i2c_common_15xx.c new file mode 100644 index 0000000..8adfe7f --- /dev/null +++ b/lpc_chip_15xx/src/i2c_common_15xx.c @@ -0,0 +1,65 @@ +/* + * @brief LPC15xx I2C Common driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initializes the LPC_I2C peripheral */ +void Chip_I2C_Init(LPC_I2C_T *pI2C) +{ + /* Enable I2C clock */ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C0); + + /* Peripheral reset control to I2C */ + Chip_SYSCTL_PeriphReset(RESET_I2C0); +} + +/* Shuts down the I2C controller block */ +void Chip_I2C_DeInit(LPC_I2C_T *pI2C) +{ + /* Disable I2C clock */ + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_I2C0); +} diff --git a/lpc_chip_15xx/src/i2cm_15xx.c b/lpc_chip_15xx/src/i2cm_15xx.c new file mode 100644 index 0000000..3d31e14 --- /dev/null +++ b/lpc_chip_15xx/src/i2cm_15xx.c @@ -0,0 +1,178 @@ +/* + * @brief LPC15xx I2C master driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set up bus speed for LPC_I2C interface */ +void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed) +{ + uint32_t scl = Chip_Clock_GetMainClockRate() / (Chip_I2C_GetClockDiv(pI2C) * busSpeed); + Chip_I2CM_SetDutyCycle(pI2C, (scl >> 1), (scl - (scl >> 1))); +} + +/* Master transfer state change handler handler */ +uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer) +{ + uint32_t status = Chip_I2CM_GetStatus(pI2C); + /* Master Lost Arbitration */ + if (status & I2C_STAT_MSTRARBLOSS) { + /* Set transfer status as Arbitration Lost */ + xfer->status = I2CM_STATUS_ARBLOST; + /* Clear Status Flags */ + Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTRARBLOSS); + } + /* Master Start Stop Error */ + else if (status & I2C_STAT_MSTSTSTPERR) { + /* Set transfer status as Bus Error */ + xfer->status = I2CM_STATUS_BUS_ERROR; + /* Clear Status Flags */ + Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTSTSTPERR); + } + /* Master is Pending */ + else if (status & I2C_STAT_MSTPENDING) { + /* Branch based on Master State Code */ + switch (Chip_I2CM_GetMasterState(pI2C)) { + /* Master idle */ + case I2C_STAT_MSTCODE_IDLE: + /* Do Nothing */ + break; + + /* Receive data is available */ + case I2C_STAT_MSTCODE_RXREADY: + /* Read Data */ + *xfer->rxBuff++ = pI2C->MSTDAT; + xfer->rxSz--; + if (xfer->rxSz) { + /* Set Continue if there is more data to read */ + Chip_I2CM_MasterContinue(pI2C); + } + else { + /* Set transfer status as OK */ + xfer->status = I2CM_STATUS_OK; + /* No data to read send Stop */ + Chip_I2CM_SendStop(pI2C); + } + break; + + /* Master Transmit available */ + case I2C_STAT_MSTCODE_TXREADY: + if (xfer->txSz) { + /* If Tx data available transmit data and continue */ + pI2C->MSTDAT = *xfer->txBuff++; + xfer->txSz--; + Chip_I2CM_MasterContinue(pI2C); + } + else { + /* If receive queued after transmit then initiate master receive transfer*/ + if (xfer->rxSz) { + /* Write Address and RW bit to data register */ + Chip_I2CM_WriteByte(pI2C, (xfer->slaveAddr << 1) | 0x1); + /* Enter to Master Transmitter mode */ + Chip_I2CM_SendStart(pI2C); + } + else { + /* If no receive queued then set transfer status as OK */ + xfer->status = I2CM_STATUS_OK; + /* Send Stop */ + Chip_I2CM_SendStop(pI2C); + } + } + break; + + case I2C_STAT_MSTCODE_NACKADR: + /* Set transfer status as NACK on address */ + xfer->status = I2CM_STATUS_NAK_ADR; + Chip_I2CM_SendStop(pI2C); + break; + + case I2C_STAT_MSTCODE_NACKDAT: + /* Set transfer status as NACK on data */ + xfer->status = I2CM_STATUS_NAK_DAT; + Chip_I2CM_SendStop(pI2C); + break; + + default: + /* Default case should not occur*/ + xfer->status = I2CM_STATUS_ERROR; + break; + } + } + else { + /* Default case should not occur */ + xfer->status = I2CM_STATUS_ERROR; + } + return xfer->status != I2CM_STATUS_BUSY; +} + +/* Transmit and Receive data in master mode */ +void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer) +{ + /* set the transfer status as busy */ + xfer->status = I2CM_STATUS_BUSY; + /* Clear controller state. */ + Chip_I2CM_ClearStatus(pI2C, I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR); + /* Write Address and RW bit to data register */ + Chip_I2CM_WriteByte(pI2C, (xfer->slaveAddr << 1) | (xfer->txSz == 0)); + /* Enter to Master Transmitter mode */ + Chip_I2CM_SendStart(pI2C); +} + +/* Transmit and Receive data in master mode */ +uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer) +{ + uint32_t ret = 0; + /* start transfer */ + Chip_I2CM_Xfer(pI2C, xfer); + + while (ret == 0) { + /* wait for status change interrupt */ + while (!Chip_I2CM_IsMasterPending(pI2C)) {} + /* call state change handler */ + ret = Chip_I2CM_XferHandler(pI2C, xfer); + } + return ret; +} diff --git a/lpc_chip_15xx/src/i2cs_15xx.c b/lpc_chip_15xx/src/i2cs_15xx.c new file mode 100644 index 0000000..95c491f --- /dev/null +++ b/lpc_chip_15xx/src/i2cs_15xx.c @@ -0,0 +1,98 @@ +/* + * @brief LPC15xx I2C slave driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Slave transfer state change handler */ +uint32_t Chip_I2CS_XferHandler(LPC_I2C_T *pI2C, const I2CS_XFER_T *xfers) +{ + uint32_t done = 0; + + uint8_t data; + uint32_t state; + + /* transfer complete? */ + if ((Chip_I2C_GetPendingInt(pI2C) & I2C_INTENSET_SLVDESEL) != 0) { + Chip_I2CS_ClearStatus(pI2C, I2C_STAT_SLVDESEL); + xfers->slaveDone(); + } + else { + /* Determine the current I2C slave state */ + state = Chip_I2CS_GetSlaveState(pI2C); + + switch (state) { + case I2C_STAT_SLVCODE_ADDR: /* Slave address received */ + /* Get slave address that needs servicing */ + data = Chip_I2CS_GetSlaveAddr(pI2C, Chip_I2CS_GetSlaveMatchIndex(pI2C)); + + /* Call address callback */ + xfers->slaveStart(data); + break; + + case I2C_STAT_SLVCODE_RX: /* Data byte received */ + /* Get received data */ + data = Chip_I2CS_ReadByte(pI2C); + done = xfers->slaveRecv(data); + break; + + case I2C_STAT_SLVCODE_TX: /* Get byte that needs to be sent */ + /* Get data to send */ + done = xfers->slaveSend(&data); + Chip_I2CS_WriteByte(pI2C, data); + break; + } + } + + if (done == 0) { + Chip_I2CS_SlaveContinue(pI2C); + } + else { + Chip_I2CS_SlaveNACK(pI2C); + } + + return done; +} diff --git a/lpc_chip_15xx/src/iap.c b/lpc_chip_15xx/src/iap.c new file mode 100644 index 0000000..656e21f --- /dev/null +++ b/lpc_chip_15xx/src/iap.c @@ -0,0 +1,179 @@ +/* + * @brief Common FLASH support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Prepare sector for write operation */ +uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_PREWRRITE_CMD; + command[1] = strSector; + command[2] = endSector; + iap_entry(command, result); + + return result[0]; +} + +/* Copy RAM to flash */ +uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_WRISECTOR_CMD; + command[1] = dstAdd; + command[2] = (uint32_t) srcAdd; + command[3] = byteswrt; + command[4] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} + +/* Erase sector */ +uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_ERSSECTOR_CMD; + command[1] = strSector; + command[2] = endSector; + command[3] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} + +/* Blank check sector */ +uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_BLANK_CHECK_SECTOR_CMD; + command[1] = strSector; + command[2] = endSector; + iap_entry(command, result); + + return result[0]; +} + +/* Read part identification number */ +uint32_t Chip_IAP_ReadPID(void) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_REPID_CMD; + iap_entry(command, result); + + return result[1]; +} + +/* Read boot code version number */ +uint32_t Chip_IAP_ReadBootCode(void) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_READ_BOOT_CODE_CMD; + iap_entry(command, result); + + return result[1] & 0xffff; +} + +/* IAP compare */ +uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_COMPARE_CMD; + command[1] = dstAdd; + command[2] = srcAdd; + command[3] = bytescmp; + iap_entry(command, result); + + return result[0]; +} + +/* Reinvoke ISP */ +uint8_t Chip_IAP_ReinvokeISP(void) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_REINVOKE_ISP_CMD; + iap_entry(command, result); + + return result[0]; +} + +/* Read the unique ID */ +uint32_t Chip_IAP_ReadUID(uint32_t* uid) +{ + uint32_t command[5], result[5]; + uint32_t i; + + command[0] = IAP_READ_UID_CMD; + iap_entry(command, result); + + for (i=0; i<4; i++) + *(uid+i) = result[i+1]; + + return result[0]; +} + +/* Erase page */ +uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage) +{ + uint32_t command[5], result[5]; + + command[0] = IAP_ERASE_PAGE_CMD; + command[1] = strPage; + command[2] = endPage; + command[3] = SystemCoreClock / 1000; + iap_entry(command, result); + + return result[0]; +} diff --git a/lpc_chip_15xx/src/iocon_15xx.c b/lpc_chip_15xx/src/iocon_15xx.c new file mode 100644 index 0000000..364d80c --- /dev/null +++ b/lpc_chip_15xx/src/iocon_15xx.c @@ -0,0 +1,56 @@ +/* + * @brief LPC15xx IOCON driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set all I/O Control pin muxing */ +void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T *pinArray, uint32_t arrayLength) +{ + uint32_t ix; + + for (ix = 0; ix < arrayLength; ix++ ) { + Chip_IOCON_PinMuxSet(pIOCON, pinArray[ix].port, pinArray[ix].pin, pinArray[ix].modefunc); + } +} diff --git a/lpc_chip_15xx/src/pinint_15xx.c b/lpc_chip_15xx/src/pinint_15xx.c new file mode 100644 index 0000000..e5e893c --- /dev/null +++ b/lpc_chip_15xx/src/pinint_15xx.c @@ -0,0 +1,48 @@ +/* + * @brief LPC15xx Pin Interrupt driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ diff --git a/lpc_chip_15xx/src/pmu_15xx.c b/lpc_chip_15xx/src/pmu_15xx.c new file mode 100644 index 0000000..74ca29a --- /dev/null +++ b/lpc_chip_15xx/src/pmu_15xx.c @@ -0,0 +1,103 @@ +/* + * @brief LPC15xx PMU chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Enter MCU Sleep mode */ +void Chip_PMU_SleepState(LPC_PMU_T *pPMU) +{ + Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG); + /* Enter sleep mode */ + __WFI(); +} + +/* Enter MCU Deep Sleep mode */ +void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU) +{ + Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG); + SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos); + /* Enter deep sleep mode */ + __WFI(); +} + +/* Enter MCU Power down mode */ +void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU) +{ + Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG); + SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos); + // There seems to be no difference between Deep sleep and power down mode, use ROM API + /* Enter power down mode */ + __WFI(); +} + +/* Enter MCU Deep Power down mode */ +void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU) +{ + Chip_PMU_ClearSleepFlags(LPC_PMU, PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG); + SCB->SCR |= (1UL << SCB_SCR_SLEEPDEEP_Pos); + pPMU->PCON = PMU_PCON_PM_DEEPPOWERDOWN; + /* Enter deep power down mode */ + __WFI(); +} + +/* Put some of the peripheral in sleep mode */ +void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode) +{ + if (SleepMode == PMU_MCU_DEEP_SLEEP) { + Chip_PMU_DeepSleepState(pPMU); + } + else if (SleepMode == PMU_MCU_POWER_DOWN) { + Chip_PMU_PowerDownState(pPMU); + } + else if (SleepMode == PMU_MCU_DEEP_PWRDOWN) { + Chip_PMU_DeepPowerDownState(pPMU); + } + else { + /* PMU_MCU_SLEEP */ + Chip_PMU_SleepState(pPMU); + } +} diff --git a/lpc_chip_15xx/src/ring_buffer.c b/lpc_chip_15xx/src/ring_buffer.c new file mode 100644 index 0000000..d18f02a --- /dev/null +++ b/lpc_chip_15xx/src/ring_buffer.c @@ -0,0 +1,167 @@ +/* + * @brief Common ring buffer support functions + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include +#include "ring_buffer.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define RB_INDH(rb) ((rb)->head & ((rb)->count - 1)) +#define RB_INDT(rb) ((rb)->tail & ((rb)->count - 1)) + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize ring buffer */ +int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count) +{ + RingBuff->data = buffer; + RingBuff->count = count; + RingBuff->itemSz = itemSize; + RingBuff->head = RingBuff->tail = 0; + + return 1; +} + +/* Insert a single item into Ring Buffer */ +int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data) +{ + uint8_t *ptr = RingBuff->data; + + /* We cannot insert when queue is full */ + if (RingBuffer_IsFull(RingBuff)) + return 0; + + ptr += RB_INDH(RingBuff) * RingBuff->itemSz; + memcpy(ptr, data, RingBuff->itemSz); + RingBuff->head++; + + return 1; +} + +/* Insert multiple items into Ring Buffer */ +int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num) +{ + uint8_t *ptr = RingBuff->data; + int cnt1, cnt2; + + /* We cannot insert when queue is full */ + if (RingBuffer_IsFull(RingBuff)) + return 0; + + /* Calculate the segment lengths */ + cnt1 = cnt2 = RingBuffer_GetFree(RingBuff); + if (RB_INDH(RingBuff) + cnt1 >= RingBuff->count) + cnt1 = RingBuff->count - RB_INDH(RingBuff); + cnt2 -= cnt1; + + cnt1 = MIN(cnt1, num); + num -= cnt1; + + cnt2 = MIN(cnt2, num); + num -= cnt2; + + /* Write segment 1 */ + ptr += RB_INDH(RingBuff) * RingBuff->itemSz; + memcpy(ptr, data, cnt1 * RingBuff->itemSz); + RingBuff->head += cnt1; + + /* Write segment 2 */ + ptr = (uint8_t *) RingBuff->data + RB_INDH(RingBuff) * RingBuff->itemSz; + data = (const uint8_t *) data + cnt1 * RingBuff->itemSz; + memcpy(ptr, data, cnt2 * RingBuff->itemSz); + RingBuff->head += cnt2; + + return cnt1 + cnt2; +} + +/* Pop single item from Ring Buffer */ +int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data) +{ + uint8_t *ptr = RingBuff->data; + + /* We cannot pop when queue is empty */ + if (RingBuffer_IsEmpty(RingBuff)) + return 0; + + ptr += RB_INDT(RingBuff) * RingBuff->itemSz; + memcpy(data, ptr, RingBuff->itemSz); + RingBuff->tail++; + + return 1; +} + +/* Pop multiple items from Ring buffer */ +int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num) +{ + uint8_t *ptr = RingBuff->data; + int cnt1, cnt2; + + /* We cannot insert when queue is empty */ + if (RingBuffer_IsEmpty(RingBuff)) + return 0; + + /* Calculate the segment lengths */ + cnt1 = cnt2 = RingBuffer_GetCount(RingBuff); + if (RB_INDT(RingBuff) + cnt1 >= RingBuff->count) + cnt1 = RingBuff->count - RB_INDT(RingBuff); + cnt2 -= cnt1; + + cnt1 = MIN(cnt1, num); + num -= cnt1; + + cnt2 = MIN(cnt2, num); + num -= cnt2; + + /* Write segment 1 */ + ptr += RB_INDT(RingBuff) * RingBuff->itemSz; + memcpy(data, ptr, cnt1 * RingBuff->itemSz); + RingBuff->tail += cnt1; + + /* Write segment 2 */ + ptr = (uint8_t *) RingBuff->data + RB_INDT(RingBuff) * RingBuff->itemSz; + data = (uint8_t *) data + cnt1 * RingBuff->itemSz; + memcpy(data, ptr, cnt2 * RingBuff->itemSz); + RingBuff->tail += cnt2; + + return cnt1 + cnt2; +} diff --git a/lpc_chip_15xx/src/ritimer_15xx.c b/lpc_chip_15xx/src/ritimer_15xx.c new file mode 100644 index 0000000..09bbe32 --- /dev/null +++ b/lpc_chip_15xx/src/ritimer_15xx.c @@ -0,0 +1,152 @@ +/* + * @brief LPC15xx RITimer driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the RIT */ +void Chip_RIT_Init(LPC_RITIMER_T *pRITimer) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_RIT); + Chip_SYSCTL_PeriphReset(RESET_RIT); + pRITimer->CTRL = 0x04; +} + +/* DeInitialize the RIT */ +void Chip_RIT_DeInit(LPC_RITIMER_T *pRITimer) +{ + pRITimer->CTRL = 0x00; + Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_RIT); +} + +/* Safely sets CTRL register bits */ +void Chip_RIT_SetCTRL(LPC_RITIMER_T *pRITimer, uint32_t val) +{ + uint32_t reg; + + reg = pRITimer->CTRL & 0xF; + pRITimer->CTRL = reg | val; +} + +/* Safely clears CTRL register bits */ +void Chip_RIT_ClearCTRL(LPC_RITIMER_T *pRITimer, uint32_t val) +{ + uint32_t reg; + + reg = pRITimer->CTRL & 0xF; + pRITimer->CTRL = reg & ~val; +} + +/* Set a tick value for the interrupt to time out */ +void Chip_RIT_SetCompareValue(LPC_RITIMER_T *pRITimer, uint64_t val) +{ + pRITimer->COMPVAL = (uint32_t) val; + pRITimer->COMPVAL_H = (uint32_t) (val >> 32); +} + +/* Returns the current timer compare value */ +uint64_t Chip_RIT_GetCompareValue(LPC_RITIMER_T *pRITimer) +{ + uint64_t val; + + val = (uint64_t) pRITimer->COMPVAL_H; + val = val << 32; + val |= (uint64_t) pRITimer->COMPVAL; + + return val; +} + +/* Sets a mask value used for bit based compare */ +void Chip_RIT_SetMaskValue(LPC_RITIMER_T *pRITimer, uint64_t mask) +{ + pRITimer->MASK = (uint32_t) mask; + pRITimer->MASK_H = (uint32_t) (mask >> 32); +} + +/* Returns the mask value used for bit based compare */ +uint64_t Chip_RIT_GetMaskValue(LPC_RITIMER_T *pRITimer) +{ + uint64_t val; + + val = (uint64_t) pRITimer->MASK_H; + val = val << 32; + val |= (uint64_t) pRITimer->MASK; + + return val; +} + +/* Sets the current timer Counter value */ +void Chip_RIT_SetCounter(LPC_RITIMER_T *pRITimer, uint64_t count) +{ + pRITimer->COUNTER = (uint32_t) count; + pRITimer->COUNTER_H = (uint32_t) (count >> 32); +} + +/* Returns the current timer Counter value */ +uint64_t Chip_RIT_GetCounter(LPC_RITIMER_T *pRITimer) +{ + uint64_t val; + + val = (uint64_t) pRITimer->COUNTER_H; + val = val << 32; + val |= (uint64_t) pRITimer->COUNTER; + + return val; +} + +/* Set timer interval value in Hz (frequency) */ +void Chip_RIT_SetTimerIntervalHz(LPC_RITIMER_T *pRITimer, uint32_t freq) +{ + uint64_t cmp_value; + + /* Determine approximate compare value based on clock rate and passed interval */ + cmp_value = (uint64_t) Chip_Clock_GetSystemClockRate(); + cmp_value = cmp_value / (uint64_t) freq; + + /* Set timer compare value and periodic mode */ + Chip_RIT_SetCompareValue(pRITimer, cmp_value); + Chip_RIT_EnableCompClear(pRITimer); +} diff --git a/lpc_chip_15xx/src/rtc_15xx.c b/lpc_chip_15xx/src/rtc_15xx.c new file mode 100644 index 0000000..f504580 --- /dev/null +++ b/lpc_chip_15xx/src/rtc_15xx.c @@ -0,0 +1,48 @@ +/* + * @brief LPC15xx RTC chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ diff --git a/lpc_chip_15xx/src/sct_15xx.c b/lpc_chip_15xx/src/sct_15xx.c new file mode 100644 index 0000000..4eaaf67 --- /dev/null +++ b/lpc_chip_15xx/src/sct_15xx.c @@ -0,0 +1,85 @@ +/* + * @brief LPC15xx State Configurable Timer driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize SCT */ +void Chip_SCT_Init(LPC_SCT_T *pSCT) +{ + uint32_t index = (uint32_t) pSCT; + index = ((index >> 14) & 0xF) - 6; + Chip_Clock_EnablePeriphClock((CHIP_SYSCTL_CLOCK_T)(SYSCTL_CLOCK_SCT0 + index)); + Chip_SYSCTL_PeriphReset((CHIP_SYSCTL_PERIPH_RESET_T)(RESET_SCT0 + index)); +} + +/* Shutdown SCT */ +void Chip_SCT_DeInit(LPC_SCT_T *pSCT) +{ + uint32_t index = (uint32_t) pSCT; + index = ((index >> 14) & 0xF) - 6; + Chip_Clock_DisablePeriphClock((CHIP_SYSCTL_CLOCK_T)(SYSCTL_CLOCK_SCT0 + index)); +} + +/* Set/Clear SCT control register */ +void Chip_SCT_SetClrControl(LPC_SCT_T *pSCT, uint32_t value, FunctionalState ena) +{ + if (ena == ENABLE) { + Chip_SCT_SetControl(pSCT, value); + } + else { + Chip_SCT_ClearControl(pSCT, value); + } +} + +/* Set Conflict resolution */ +void Chip_SCT_SetConflictResolution(LPC_SCT_T *pSCT, uint8_t outnum, uint8_t value) +{ + uint32_t tem; + + tem = pSCT->RES & (~(0x03 << (2 * outnum))); + pSCT->RES = tem | (value << (2 * outnum)); +} diff --git a/lpc_chip_15xx/src/sct_pwm_15xx.c b/lpc_chip_15xx/src/sct_pwm_15xx.c new file mode 100644 index 0000000..841fca8 --- /dev/null +++ b/lpc_chip_15xx/src/sct_pwm_15xx.c @@ -0,0 +1,85 @@ +/* + * @brief LPC15xx State Configurable Timer PWM driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Setup the OUTPUT pin corresponding to the PWM index */ +void Chip_SCTPWM_SetOutPin(LPC_SCT_T *pSCT, uint8_t index, uint8_t pin) +{ + int ix = (int) index; + pSCT->EVENT[ix].CTRL = index | (1 << 12); + pSCT->EVENT[ix].STATE = 1; + pSCT->OUT[pin].SET = 1; + pSCT->OUT[pin].CLR = 1 << ix; + + /* Clear the output in-case of conflict */ + pSCT->RES = (pSCT->RES & ~(3 << (pin << 1))) | (0x01 << (pin << 1)); + + /* Set and Clear do not depend on direction */ + pSCT->OUTPUTDIRCTRL = (pSCT->OUTPUTDIRCTRL & ~(3 << (pin << 1))); +} + +/* Set the PWM frequency */ +void Chip_SCTPWM_SetRate(LPC_SCT_T *pSCT, uint32_t freq) +{ + uint32_t rate; + + rate = Chip_Clock_GetSystemClockRate() / freq;; + + /* Stop the SCT before configuration */ + Chip_SCTPWM_Stop(pSCT); + + /* Set MATCH0 for max limit */ + pSCT->REGMODE = 0; + Chip_SCT_SetMatchCount(pSCT, SCT_MATCH_0, 0); + Chip_SCT_SetMatchReload(pSCT, SCT_MATCH_0, rate); + pSCT->EVENT[0].CTRL = 1 << 12; + pSCT->EVENT[0].STATE = 1; + + /* Set SCT Counter to count 32-bits and reset to 0 after reaching MATCH0 */ + Chip_SCT_Config(pSCT, SCT_CONFIG_32BIT_COUNTER | SCT_CONFIG_AUTOLIMIT_L); +} diff --git a/lpc_chip_15xx/src/sctipu_15xx.c b/lpc_chip_15xx/src/sctipu_15xx.c new file mode 100644 index 0000000..d0d4042 --- /dev/null +++ b/lpc_chip_15xx/src/sctipu_15xx.c @@ -0,0 +1,63 @@ +/* + * @brief LPC15xx SCTIPU driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Sets up an configuration and input source for a SCTIPU output channel */ +void Chip_SCTIPU_ConfigSample(uint8_t ch, uint8_t useb, uint8_t sampIn, uint8_t useLatch) +{ + uint32_t reg; + + /* Get current sample control register states and mask off channel + specific bits. Set reserved bits states to 0. */ + reg = LPC_SCTIPU->SAMPLE_CTRL & ~(SCTIPU_CTRL_INSELMASK(ch) | + SCTIPU_CTRL_SAMPENDMASK(ch) | SCTIPU_CTRL_LATCHENMASK(ch) | + SCTIPU_RESERVED_BITS); + + /* Setup channel specific configuration */ + reg |= SCTIPU_CTRL_INSEL(ch, useb) | SCTIPU_CTRL_SAMPENDSEL(ch, sampIn) | + SCTIPU_CTRL_LATCHENSEL(ch, useLatch); + LPC_SCTIPU->SAMPLE_CTRL = reg; +} diff --git a/lpc_chip_15xx/src/spi_15xx.c b/lpc_chip_15xx/src/spi_15xx.c new file mode 100644 index 0000000..4d490ee --- /dev/null +++ b/lpc_chip_15xx/src/spi_15xx.c @@ -0,0 +1,307 @@ +/* + * @brief LPC15xx SPI driver + * + * @note + * Copyright(C) NXP Semiconductors, 2014 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +STATIC void SPI_Send_Data_RxIgnore(LPC_SPI_T *pSPI, + SPI_DATA_SETUP_T *pXfSetup) +{ + if (pXfSetup->TxCnt == (pXfSetup->Length - 1)) { + Chip_SPI_SendLastFrame_RxIgnore(pSPI, pXfSetup->pTx[pXfSetup->TxCnt], pXfSetup->DataSize, pXfSetup->ssel); + } + else { + Chip_SPI_SendMidFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt]); + } + + pXfSetup->TxCnt++; +} + +STATIC void SPI_Send_Data(LPC_SPI_T *pSPI, + SPI_DATA_SETUP_T *pXfSetup) +{ + if (pXfSetup->TxCnt == (pXfSetup->Length - 1)) { + Chip_SPI_SendLastFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt], pXfSetup->DataSize, pXfSetup->ssel); + } + else { + Chip_SPI_SendMidFrame(pSPI, pXfSetup->pTx[pXfSetup->TxCnt]); + } + + pXfSetup->TxCnt++; +} + +STATIC void SPI_Send_Dummy(LPC_SPI_T *pSPI, + SPI_DATA_SETUP_T *pXfSetup) +{ + if (pXfSetup->RxCnt == (pXfSetup->Length - 1)) { + Chip_SPI_SendLastFrame(pSPI, 0x55, pXfSetup->DataSize, pXfSetup->ssel); + } + else { + Chip_SPI_SendMidFrame(pSPI, 0x55); + } +} + +STATIC void SPI_Receive_Data(LPC_SPI_T *pSPI, + SPI_DATA_SETUP_T *pXfSetup) +{ + pXfSetup->pRx[pXfSetup->RxCnt] = Chip_SPI_ReceiveFrame(pSPI); + pXfSetup->RxCnt++; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Calculate the Clock Rate Divider for SPI Peripheral */ +uint32_t Chip_SPI_CalClkRateDivider(LPC_SPI_T *pSPI, uint32_t bitRate) +{ + uint32_t SPIClk; + uint32_t DivVal; + + /* Get SPI clock rate */ + SPIClk = Chip_Clock_GetSystemClockRate(); /*The peripheral clock for both SPIs is the system clock*/ + + DivVal = SPIClk / bitRate; + + return DivVal - 1; +} + +/* Set SPI Config register */ +void Chip_SPI_SetConfig(LPC_SPI_T *pSPI, SPI_CFG_T *pConfig) +{ + uint32_t EnStat = pSPI->CFG & SPI_CFG_SPI_EN; + + /* Disable before update CFG register */ + if (EnStat) { + Chip_SPI_Disable(pSPI); + } + + /* SPI Configure */ + pSPI->CFG = ((uint32_t) pConfig->ClockMode) | ((uint32_t) pConfig->DataOrder) | ((uint32_t) pConfig->Mode) | + ((uint32_t) pConfig->SSELPol); + + /* Rate Divider setting */ + pSPI->DIV = SPI_DIV_VAL(pConfig->ClkDiv); + + /* Clear status flag*/ + Chip_SPI_ClearStatus( + pSPI, + SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD | + SPI_STAT_FORCE_EOT); + + /* Return the previous state */ + if (EnStat) { + Chip_SPI_Enable(pSPI); + } +} + +void Chip_SPI_Init(LPC_SPI_T *pSPI) +{ + if (pSPI == LPC_SPI1) { + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SPI1); + Chip_SYSCTL_PeriphReset(RESET_SPI1); + } + else { + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SPI0); + Chip_SYSCTL_PeriphReset(RESET_SPI0); + } +} + +/* De-initializes the SPI peripheral */ +void Chip_SPI_DeInit(LPC_SPI_T *pSPI) +{ + Chip_SPI_Disable(pSPI); + + Chip_Clock_DisablePeriphClock((pSPI == LPC_SPI1) ? SYSCTL_CLOCK_SPI1 : SYSCTL_CLOCK_SPI0); +} + +/* Configure SPI Delay parameters */ +void Chip_SPI_DelayConfig(LPC_SPI_T *pSPI, SPI_DELAY_CONFIG_T *pConfig) +{ + pSPI->DLY = SPI_DLY_PRE_DELAY(pConfig->PreDelay); + pSPI->DLY |= SPI_DLY_POST_DELAY(pConfig->PostDelay); + pSPI->DLY |= SPI_DLY_FRAME_DELAY(pConfig->FrameDelay); + if (pConfig->TransferDelay) { + pSPI->DLY |= SPI_DLY_TRANSFER_DELAY(pConfig->TransferDelay - 1); + } +} + +/* Disable/Enable Interrupt */ +void Chip_SPI_Int_Cmd(LPC_SPI_T *pSPI, uint32_t IntMask, FunctionalState NewState) +{ + if (NewState == ENABLE) { + pSPI->INTENSET |= (IntMask & SPI_INTENSET_BITMASK); + } + else { + pSPI->INTENCLR = (IntMask & SPI_INTENCLR_BITMASK); + } +} + +/*Send and Receive SPI Data */ +uint32_t Chip_SPI_RWFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup) +{ + uint32_t Status; + /* Clear status */ + Chip_SPI_ClearStatus( + pSPI, + SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD | + SPI_STAT_FORCE_EOT); + Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, pXfSetup->ssel | SPI_TXCTL_EOF); + pXfSetup->TxCnt = pXfSetup->RxCnt = 0; + while ((pXfSetup->TxCnt < pXfSetup->Length) || + (pXfSetup->RxCnt < pXfSetup->Length)) { + Status = Chip_SPI_GetStatus(pSPI); + + /* In case of TxReady */ + if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) { + SPI_Send_Data(pSPI, pXfSetup); + } + + /*In case of Rx ready */ + if ((Status & SPI_STAT_RXRDY) && (pXfSetup->RxCnt < pXfSetup->Length)) { + SPI_Receive_Data(pSPI, pXfSetup); + } + } + /* Check error */ + if (Chip_SPI_GetStatus(pSPI) & (SPI_STAT_RXOV | SPI_STAT_TXUR)) { + return 0; + } + return pXfSetup->TxCnt; +} + +uint32_t Chip_SPI_WriteFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup) +{ + /* Clear status */ + Chip_SPI_ClearStatus( + pSPI, + SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD | + SPI_STAT_FORCE_EOT); + Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, pXfSetup->ssel | SPI_TXCTL_EOF | SPI_TXCTL_RXIGNORE); + pXfSetup->TxCnt = pXfSetup->RxCnt = 0; + while (pXfSetup->TxCnt < pXfSetup->Length) { + /* Wait for TxReady */ + while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY)) {} + + SPI_Send_Data_RxIgnore(pSPI, pXfSetup); + + } + + /* Make sure the last frame sent completely*/ + while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_SSD)) {} + Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_SSD); + + /* Check overrun error */ + if (Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXUR) { + return 0; + } + return pXfSetup->TxCnt; +} + +uint32_t Chip_SPI_ReadFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup) +{ + /* Clear status */ + Chip_SPI_ClearStatus( + pSPI, + SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR | SPI_STAT_CLR_SSA | SPI_STAT_CLR_SSD | + SPI_STAT_FORCE_EOT); + Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, pXfSetup->ssel | SPI_TXCTL_EOF); + pXfSetup->TxCnt = pXfSetup->RxCnt = 0; + while (pXfSetup->RxCnt < pXfSetup->Length) { + /* Wait for TxReady */ + while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_TXRDY)) {} + + SPI_Send_Dummy(pSPI, pXfSetup); + + /* Wait for receive data */ + while (!(Chip_SPI_GetStatus(pSPI) & SPI_STAT_RXRDY)) {} + + SPI_Receive_Data(pSPI, pXfSetup); + + } + /* Check overrun error */ + if (Chip_SPI_GetStatus(pSPI) & (SPI_STAT_RXOV | SPI_STAT_TXUR)) { + return 0; + } + return pXfSetup->RxCnt; +} + +/* SPI Interrupt Read/Write with 8-bit frame width */ +Status Chip_SPI_Int_RWFrames(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup) +{ + uint32_t Status; + + Status = Chip_SPI_GetStatus(pSPI); + /* Check error in STAT register */ + if (Status & (SPI_STAT_RXOV | SPI_STAT_TXUR)) { + /* Clear errors */ + Chip_SPI_ClearStatus(pSPI, SPI_STAT_CLR_RXOV | SPI_STAT_CLR_TXUR); + return ERROR; + } + + if (pXfSetup->TxCnt == 0) { + if (pXfSetup->pRx == NULL) { + Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, pXfSetup->ssel | SPI_TXCTL_EOF | SPI_TXCTL_RXIGNORE); + } + else { + Chip_SPI_SetControlInfo(pSPI, pXfSetup->DataSize, pXfSetup->ssel | SPI_TXCTL_EOF); + } + } + + if (pXfSetup->pRx == NULL) { + if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) { + SPI_Send_Data_RxIgnore(pSPI, pXfSetup); + } + } + else { + /* check if Tx ready */ + if ((Status & SPI_STAT_TXRDY) && (pXfSetup->TxCnt < pXfSetup->Length)) { + SPI_Send_Data(pSPI, pXfSetup); + } + + /* check if RX FIFO contains data */ + if ((Status & SPI_STAT_RXRDY) && (pXfSetup->RxCnt < pXfSetup->Length)) { + SPI_Receive_Data(pSPI, pXfSetup); + } + } + + return SUCCESS; +} diff --git a/lpc_chip_15xx/src/stopwatch_15xx.c b/lpc_chip_15xx/src/stopwatch_15xx.c new file mode 100644 index 0000000..751ead2 --- /dev/null +++ b/lpc_chip_15xx/src/stopwatch_15xx.c @@ -0,0 +1,106 @@ +/* + * @brief LPC15xx specific stopwatch implementation + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" +#include "stopwatch.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* Precompute these to optimize runtime */ +static uint32_t ticksPerSecond; +static uint32_t ticksPerMs; +static uint32_t ticksPerUs; + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize stopwatch */ +void StopWatch_Init(void) +{ + /* Use Repetitive Interrupt Timer (RIT) */ + Chip_RIT_Init(LPC_RITIMER); + Chip_RIT_SetCompareValue(LPC_RITIMER, (uint32_t) 0xFFFFFFFF); + Chip_RIT_EnableCompClear(LPC_RITIMER); + Chip_RIT_Enable(LPC_RITIMER); + + /* Pre-compute tick rate. */ + ticksPerSecond = Chip_Clock_GetSystemClockRate(); + ticksPerMs = ticksPerSecond / 1000; + ticksPerUs = ticksPerSecond / 1000000; +} + +/* Start a stopwatch */ +uint32_t StopWatch_Start(void) +{ + /* Return the current timer count. */ + return (uint32_t) Chip_RIT_GetCounter(LPC_RITIMER); +} + +/* Returns number of ticks per second of the stopwatch timer */ +uint32_t StopWatch_TicksPerSecond(void) +{ + return ticksPerSecond; +} + +/* Converts from stopwatch ticks to mS. */ +uint32_t StopWatch_TicksToMs(uint32_t ticks) +{ + return ticks / ticksPerMs; +} + +/* Converts from stopwatch ticks to uS. */ +uint32_t StopWatch_TicksToUs(uint32_t ticks) +{ + return ticks / ticksPerUs; +} + +/* Converts from mS to stopwatch ticks. */ +uint32_t StopWatch_MsToTicks(uint32_t mS) +{ + return mS * ticksPerMs; +} + +/* Converts from uS to stopwatch ticks. */ +uint32_t StopWatch_UsToTicks(uint32_t uS) +{ + return uS * ticksPerUs; +} diff --git a/lpc_chip_15xx/src/swm_15xx.c b/lpc_chip_15xx/src/swm_15xx.c new file mode 100644 index 0000000..6a58c0b --- /dev/null +++ b/lpc_chip_15xx/src/swm_15xx.c @@ -0,0 +1,107 @@ +/* + * @brief LPC15xx Switch Matrix driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define PINASSIGN_IDX(movable) (((movable) >> 4)) +#define PINSHIFT(movable) (8 * ((movable) & (0xF))) + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Assign movable pin function to physical pin in Switch Matrix */ +void Chip_SWM_MovablePinAssign(CHIP_SWM_PIN_MOVABLE_T movable, uint8_t pin) +{ + uint32_t temp; + int pinshift = PINSHIFT(movable), regIndex = PINASSIGN_IDX(movable); + + temp = LPC_SWM->PINASSIGN[regIndex] & (~(0xFF << pinshift)); + LPC_SWM->PINASSIGN[regIndex] = temp | (pin << pinshift); +} + +/* Enables a fixed function pin in the Switch Matrix */ +void Chip_SWM_EnableFixedPin(CHIP_SWM_PIN_FIXED_T pin) +{ + uint32_t regOff, pinPos; + + pinPos = ((uint32_t) pin) & 0x1F; + regOff = ((uint32_t) pin) >> 7; + + /* Set low to enable fixed pin */ + LPC_SWM->PINENABLE[regOff] &= ~(1 << pinPos); +} + +/* Disables a fixed function pin in the Switch Matrix */ +void Chip_SWM_DisableFixedPin(CHIP_SWM_PIN_FIXED_T pin) +{ + uint32_t regOff, pinPos; + + pinPos = ((uint32_t) pin) & 0x1F; + regOff = ((uint32_t) pin) >> 7; + + /* Set low to enable fixed pin */ + LPC_SWM->PINENABLE[regOff] |= (1 << pinPos); +} + +/* Enables or disables a fixed function pin in the Switch Matrix */ +void Chip_SWM_FixedPinEnable(CHIP_SWM_PIN_FIXED_T pin, bool enable) +{ + if (enable) { + Chip_SWM_EnableFixedPin(pin); + } + else { + Chip_SWM_DisableFixedPin(pin); + } +} + +/* Tests whether a fixed function pin is enabled or disabled in the Switch Matrix */ +bool Chip_SWM_IsFixedPinEnabled(CHIP_SWM_PIN_FIXED_T pin) +{ + uint32_t regOff, pinPos; + + pinPos = ((uint32_t) pin) & 0x1F; + regOff = ((uint32_t) pin) >> 7; + + return (bool) ((LPC_SWM->PINENABLE[regOff] & (1 << pinPos)) == 0); +} diff --git a/lpc_chip_15xx/src/sysctl_15xx.c b/lpc_chip_15xx/src/sysctl_15xx.c new file mode 100644 index 0000000..d02e3a3 --- /dev/null +++ b/lpc_chip_15xx/src/sysctl_15xx.c @@ -0,0 +1,121 @@ +/* + * @brief LPC15XX System Control functions + * + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* PDWAKECFG register mask */ +#define PDWAKEUPUSEMASK 0x00000000 +#define PDWAKEUPMASKTMP 0x01FFFF78 + +/* PDRUNCFG register mask */ +#define PDRUNCFGUSEMASK 0x00000000 +#define PDRUNCFGMASKTMP 0x01FFFF78 + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Returns the computed value for a frequency measurement cycle */ +uint32_t Chip_SYSCTL_GetCompFreqMeas(uint32_t refClockRate) +{ + uint32_t capval; + uint64_t clkrate = 0; + + /* Get raw capture value */ + capval = Chip_SYSCTL_GetRawFreqMeasCapval(); + + /* Limit CAPVAL check */ + if (capval > 2) { + clkrate = (((uint64_t) capval - 2) * (uint64_t) refClockRate) / 0x4000; + } + + return (uint32_t) clkrate; +} + +/* De-assert reset for a peripheral */ +void Chip_SYSCTL_AssertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph) +{ + if (periph >= 32) { + LPC_SYSCTL->PRESETCTRL[1] |= (1 << ((uint32_t) periph - 32)); + } + else { + LPC_SYSCTL->PRESETCTRL[0] |= (1 << (uint32_t) periph); + } +} + +/* Assert reset for a peripheral */ +void Chip_SYSCTL_DeassertPeriphReset(CHIP_SYSCTL_PERIPH_RESET_T periph) +{ + if (periph >= 32) { + LPC_SYSCTL->PRESETCTRL[1] &= ~(1 << ((uint32_t) periph - 32)); + } + else { + LPC_SYSCTL->PRESETCTRL[0] &= ~(1 << (uint32_t) periph); + } +} + +/* Setup wakeup behaviour from deep sleep */ +void Chip_SYSCTL_SetWakeup(uint32_t wakeupmask) +{ + /* Update new value */ + LPC_SYSCTL->PDWAKECFG = PDWAKEUPUSEMASK | (wakeupmask & PDWAKEUPMASKTMP); +} + +/* Power down one or more blocks or peripherals */ +void Chip_SYSCTL_PowerDown(uint32_t powerdownmask) +{ + uint32_t pdrun; + + pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP; + pdrun |= (powerdownmask & PDRUNCFGMASKTMP); + + LPC_SYSCTL->PDRUNCFG = (pdrun | PDRUNCFGUSEMASK); +} + +/* Power up one or more blocks or peripherals */ +void Chip_SYSCTL_PowerUp(uint32_t powerupmask) +{ + uint32_t pdrun; + + pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP; + pdrun &= ~(powerupmask & PDRUNCFGMASKTMP); + + LPC_SYSCTL->PDRUNCFG = (pdrun | PDRUNCFGUSEMASK); +} diff --git a/lpc_chip_15xx/src/sysinit_15xx.c b/lpc_chip_15xx/src/sysinit_15xx.c new file mode 100644 index 0000000..10fe092 --- /dev/null +++ b/lpc_chip_15xx/src/sysinit_15xx.c @@ -0,0 +1,134 @@ +/* + * @brief LPC15xx Chip specific SystemInit + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Clock and PLL initialization based on the internal oscillator */ +void Chip_SetupIrcClocking(void) +{ + volatile int i; + + /* Powerup main IRC (likely already powered up) */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRC_PD); + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRCOUT_PD); + + /* Set system PLL input to IRC */ + Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC); + + /* Power down PLL to change the PLL divider ratio */ + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD); + + /* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz + MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz + FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range) */ + Chip_Clock_SetupSystemPLL(5, 2); + + /* Powerup system PLL */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD); + + /* Wait for PLL to lock */ + while (!Chip_Clock_IsSystemPLLLocked()) {} + + /* Set system clock divider to 1 */ + Chip_Clock_SetSysClockDiv(1); + + /* Setup FLASH access timing for 72MHz */ + Chip_FMC_SetFLASHAccess(SYSCTL_FLASHTIM_72MHZ_CPU); + + /* Set main clock source to the system PLL. This will drive 72MHz + for the main clock */ + Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_SYSPLLOUT); +} + +/* Clock and PLL initialization based on the external oscillator */ +void Chip_SetupXtalClocking(void) +{ + volatile int i; + + /* Powerup main oscillator */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSOSC_PD); + + /* Wait 200us for OSC to be stablized, no status + indication, dummy wait. */ + for (i = 0; i < 0x200; i++) {} + + /* Set system PLL input to main oscillator */ + Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_MAINOSC); + + /* Power down PLL to change the PLL divider ratio */ + Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD); + + /* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz + MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz + FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range) */ + Chip_Clock_SetupSystemPLL(5, 2); + + /* Powerup system PLL */ + Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD); + + /* Wait for PLL to lock */ + while (!Chip_Clock_IsSystemPLLLocked()) {} + + /* Set system clock divider to 1 */ + Chip_Clock_SetSysClockDiv(1); + + /* Setup FLASH access timing for 72MHz */ + Chip_FMC_SetFLASHAccess(SYSCTL_FLASHTIM_72MHZ_CPU); + + /* Set main clock source to the system PLL. This will drive 72MHz + for the main clock */ + Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_SYSPLLOUT); +} + +/* Set up and initialize hardware prior to call to main */ +void Chip_SystemInit(void) +{ + /* Initial internal clocking */ + Chip_SetupIrcClocking(); +} diff --git a/lpc_chip_15xx/src/uart_15xx.c b/lpc_chip_15xx/src/uart_15xx.c new file mode 100644 index 0000000..9bef30b --- /dev/null +++ b/lpc_chip_15xx/src/uart_15xx.c @@ -0,0 +1,241 @@ +/* + * @brief LPC15XX USART0 driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licenser disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/* Return UART clock ID from the UART register address */ +static CHIP_SYSCTL_CLOCK_T getUARTClockID(LPC_USART_T *pUART) +{ + if (pUART == LPC_USART0) { + return SYSCTL_CLOCK_UART0; + } + else if (pUART == LPC_USART1) { + return SYSCTL_CLOCK_UART1; + } + + return SYSCTL_CLOCK_UART2; +} + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the UART peripheral */ +void Chip_UART_Init(LPC_USART_T *pUART) +{ + /* Enable USART clock */ + Chip_Clock_EnablePeriphClock(getUARTClockID(pUART)); + + /* UART reset */ + if (pUART == LPC_USART0) { + /* Peripheral reset control to USART0 */ + Chip_SYSCTL_PeriphReset(RESET_UART0); + } + else if (pUART == LPC_USART1) { + /* Peripheral reset control to USART1 */ + Chip_SYSCTL_PeriphReset(RESET_UART1); + } + else { + /* Peripheral reset control to USART2 */ + Chip_SYSCTL_PeriphReset(RESET_UART2); + } +} + +/* Initialize the UART peripheral */ +void Chip_UART_DeInit(LPC_USART_T *pUART) +{ + /* Disable USART clock */ + Chip_Clock_DisablePeriphClock(getUARTClockID(pUART)); +} + +/* Transmit a byte array through the UART peripheral (non-blocking) */ +int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes) +{ + int sent = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Send until the transmit FIFO is full or out of bytes */ + while ((sent < numBytes) && + ((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0)) { + Chip_UART_SendByte(pUART, *p8); + p8++; + sent++; + } + + return sent; +} + +/* Transmit a byte array through the UART peripheral (blocking) */ +int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes) +{ + int pass, sent = 0; + uint8_t *p8 = (uint8_t *) data; + + while (numBytes > 0) { + pass = Chip_UART_Send(pUART, p8, numBytes); + numBytes -= pass; + sent += pass; + p8 += pass; + } + + return sent; +} + +/* Read data through the UART peripheral (non-blocking) */ +int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes) +{ + int readBytes = 0; + uint8_t *p8 = (uint8_t *) data; + + /* Send until the transmit FIFO is full or out of bytes */ + while ((readBytes < numBytes) && + ((Chip_UART_GetStatus(pUART) & UART_STAT_RXRDY) != 0)) { + *p8 = Chip_UART_ReadByte(pUART); + p8++; + readBytes++; + } + + return readBytes; +} + +/* Read data through the UART peripheral (blocking) */ +int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes) +{ + int pass, readBytes = 0; + uint8_t *p8 = (uint8_t *) data; + + while (readBytes < numBytes) { + pass = Chip_UART_Read(pUART, p8, numBytes); + numBytes -= pass; + readBytes += pass; + p8 += pass; + } + + return readBytes; +} + +/* Set baud rate for UART */ +void Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate) +{ + uint32_t baudRateGenerator; + baudRateGenerator = Chip_Clock_GetUARTBaseClockRate() / (16 * baudrate); + pUART->BRG = baudRateGenerator - 1; /* baud rate */ +} + +/* Set baud rate for UART using RTC32K oscillator */ +void Chip_UART_SetBaudWithRTC32K(LPC_USART_T *pUART, uint32_t baudrate) +{ + /* Simple integer divide */ + pUART->BRG = (Chip_Clock_GetRTCOscRate() / (3 * baudrate)) - 1; + + pUART->CFG |= UART_MODE_32K; +} + +/* UART receive-only interrupt handler for ring buffers */ +void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB) +{ + /* New data will be ignored if data not popped in time */ + while ((Chip_UART_GetStatus(pUART) & UART_STAT_RXRDY) != 0) { + uint8_t ch = Chip_UART_ReadByte(pUART); + RingBuffer_Insert(pRB, &ch); + } +} + +/* UART transmit-only interrupt handler for ring buffers */ +void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB) +{ + uint8_t ch; + + /* Fill FIFO until full or until TX ring buffer is empty */ + while (((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0) && + RingBuffer_Pop(pRB, &ch)) { + Chip_UART_SendByte(pUART, ch); + } +} + +/* Populate a transmit ring buffer and start UART transmit */ +uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int count) +{ + uint32_t ret; + uint8_t *p8 = (uint8_t *) data; + + /* Don't let UART transmit ring buffer change in the UART IRQ handler */ + Chip_UART_IntDisable(pUART, UART_INTEN_TXRDY); + + /* Move as much data as possible into transmit ring buffer */ + ret = RingBuffer_InsertMult(pRB, p8, count); + Chip_UART_TXIntHandlerRB(pUART, pRB); + + /* Add additional data to transmit ring buffer if possible */ + ret += RingBuffer_InsertMult(pRB, (p8 + ret), (count - ret)); + + /* Enable UART transmit interrupt */ + Chip_UART_IntEnable(pUART, UART_INTEN_TXRDY); + + return ret; +} + +/* Copy data from a receive ring buffer */ +int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes) +{ + (void) pUART; + + return RingBuffer_PopMult(pRB, (uint8_t *) data, bytes); +} + +/* UART receive/transmit interrupt handler for ring buffers */ +void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB) +{ + /* Handle transmit interrupt if enabled */ + if ((Chip_UART_GetStatus(pUART) & UART_STAT_TXRDY) != 0) { + Chip_UART_TXIntHandlerRB(pUART, pTXRB); + + /* Disable transmit interrupt if the ring buffer is empty */ + if (RingBuffer_IsEmpty(pTXRB)) { + Chip_UART_IntDisable(pUART, UART_INTEN_TXRDY); + } + } + + /* Handle receive interrupt */ + Chip_UART_RXIntHandlerRB(pUART, pRXRB); +} diff --git a/lpc_chip_15xx/src/wwdt_15xx.c b/lpc_chip_15xx/src/wwdt_15xx.c new file mode 100644 index 0000000..756d688 --- /dev/null +++ b/lpc_chip_15xx/src/wwdt_15xx.c @@ -0,0 +1,72 @@ +/* + * @brief LPC15xx WWDT chip driver + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "chip.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Initialize the Watchdog timer */ +void Chip_WWDT_Init(LPC_WWDT_T *pWWDT) +{ + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_WDT); + + /* Disable watchdog */ + pWWDT->MOD = 0; + pWWDT->TC = 0xFF; + pWWDT->WARNINT = 0x3FF; + pWWDT->WINDOW = 0xFFFFFF; +} + +/* Clear WWDT interrupt status flags */ +void Chip_WWDT_ClearStatusFlag(LPC_WWDT_T *pWWDT, uint32_t status) +{ + if (status & WWDT_WDMOD_WDTOF) { + pWWDT->MOD &= (~WWDT_WDMOD_WDTOF) & WWDT_WDMOD_BITMASK; + } + + if (status & WWDT_WDMOD_WDINT) { + pWWDT->MOD |= WWDT_WDMOD_WDINT; + } +} diff --git a/lpc_chip_15xx/version.txt b/lpc_chip_15xx/version.txt new file mode 100644 index 0000000..ac766ae --- /dev/null +++ b/lpc_chip_15xx/version.txt @@ -0,0 +1,3 @@ +LPCOPEN VERSION: 2_20 +RELEASE DATE: +Mon 01/04/2016 diff --git a/periph_blinky/.cproject b/periph_blinky/.cproject new file mode 100644 index 0000000..e412d5a --- /dev/null +++ b/periph_blinky/.cproject @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_0="" property_2="LPC15xx_256K.cfx" property_3="NXP" property_4="LPC1549" property_count="5" version="70200"/> +<infoList vendor="NXP"> +<info chip="LPC1549" connectscript="LPC15RunBootRomConnect.scp" flash_driver="LPC15xx_256K.cfx" match_id="0x0" name="LPC1549" resetscript="LPC15RunBootRomReset.scp" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC1549</name> +<family>LPC15xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" id="Ram0_16" location="0x2000000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram1_16" location="0x2004000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram2_4" location="0x2008000" size="0x1000"/> +<peripheralInstance derived_from="V7M_MPU" determined="infoFile" id="MPU" location="0xe000ed90"/> +<peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/> +<peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/> +<peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/> +<peripheralInstance derived_from="GPIO-PORT" determined="infoFile" id="GPIO-PORT" location="0x1c000000"/> +<peripheralInstance derived_from="DMA" determined="infoFile" id="DMA" location="0x1c004000"/> +<peripheralInstance derived_from="USB" determined="infoFile" id="USB" location="0x1c00c000"/> +<peripheralInstance derived_from="CRC" determined="infoFile" id="CRC" location="0x1c010000"/> +<peripheralInstance derived_from="SCT0" determined="infoFile" id="SCT0" location="0x1c018000"/> +<peripheralInstance derived_from="SCT1" determined="infoFile" id="SCT1" location="0x1c01c000"/> +<peripheralInstance derived_from="SCT2" determined="infoFile" id="SCT2" location="0x1c020000"/> +<peripheralInstance derived_from="SCT3" determined="infoFile" id="SCT3" location="0x1c024000"/> +<peripheralInstance derived_from="ADC0" determined="infoFile" id="ADC0" location="0x40000000"/> +<peripheralInstance derived_from="DAC" determined="infoFile" id="DAC" location="0x40004000"/> +<peripheralInstance derived_from="ACMP" determined="infoFile" id="ACMP" location="0x40008000"/> +<peripheralInstance derived_from="INMUX" determined="infoFile" id="INMUX" location="0x40014000"/> +<peripheralInstance derived_from="RTC" determined="infoFile" id="RTC" location="0x40028000"/> +<peripheralInstance derived_from="WWDT" determined="infoFile" id="WWDT" location="0x4002c000"/> +<peripheralInstance derived_from="SWM" determined="infoFile" id="SWM" location="0x40038000"/> +<peripheralInstance derived_from="PMU" determined="infoFile" id="PMU" location="0x4003c000"/> +<peripheralInstance derived_from="USART0" determined="infoFile" id="USART0" location="0x40040000"/> +<peripheralInstance derived_from="USART1" determined="infoFile" id="USART1" location="0x40044000"/> +<peripheralInstance derived_from="SPI0" determined="infoFile" id="SPI0" location="0x40048000"/> +<peripheralInstance derived_from="SPI1" determined="infoFile" id="SPI1" location="0x4004c000"/> +<peripheralInstance derived_from="I2C0" determined="infoFile" id="I2C0" location="0x40050000"/> +<peripheralInstance derived_from="QEI" determined="infoFile" id="QEI" location="0x40058000"/> +<peripheralInstance derived_from="SYSCON" determined="infoFile" id="SYSCON" location="0x40074000"/> +<peripheralInstance derived_from="ADC1" determined="infoFile" id="ADC1" location="0x40080000"/> +<peripheralInstance derived_from="MRT" determined="infoFile" id="MRT" location="0x400a0000"/> +<peripheralInstance derived_from="PINT" determined="infoFile" id="PINT" location="0x400a4000"/> +<peripheralInstance derived_from="GINT0" determined="infoFile" id="GINT0" location="0x400a8000"/> +<peripheralInstance derived_from="GINT1" determined="infoFile" id="GINT1" location="0x400ac000"/> +<peripheralInstance derived_from="RIT" determined="infoFile" id="RIT" location="0x400b4000"/> +<peripheralInstance derived_from="SCTIPU" determined="infoFile" id="SCTIPU" location="0x400b8000"/> +<peripheralInstance derived_from="FLASHCTRL" determined="infoFile" id="FLASHCTRL" location="0x400bc000"/> +<peripheralInstance derived_from="USART2" determined="infoFile" id="USART2" location="0x400c0000"/> +<peripheralInstance derived_from="C-CAN0" determined="infoFile" id="C-CAN0" location="0x400f0000"/> +<peripheralInstance derived_from="IOCON" determined="infoFile" id="IOCON" location="0x400f8000"/> +</chip> +<processor> +<name gcc_name="cortex-m3">Cortex-M3</name> +<family>Cortex-M</family> +</processor> +<link href="LPC15xx_peripheral.xme" show="embed" type="simple"/> +</info> +</infoList> +</TargetConfig> + + diff --git a/periph_blinky/.project b/periph_blinky/.project new file mode 100644 index 0000000..79e1771 --- /dev/null +++ b/periph_blinky/.project @@ -0,0 +1,28 @@ + + + periph_blinky + + + lpc_chip_15xx + lpc_board_nxp_lpcxpresso_1549 + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/periph_blinky/.settings/language.settings.xml b/periph_blinky/.settings/language.settings.xml new file mode 100644 index 0000000..5d2dd35 --- /dev/null +++ b/periph_blinky/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/periph_blinky/example/readme.txt b/periph_blinky/example/readme.txt new file mode 100644 index 0000000..7e7040f --- /dev/null +++ b/periph_blinky/example/readme.txt @@ -0,0 +1,16 @@ +LPC15xx Simple blinky example + +Example description: +-------------------- +The blinky example flashes an LED in a periodic rate. + + +Special connection requirements: +-------------------------------- +There are no special connection requirements for this example. + +Build procedures: +----------------- +Visit the LPCOpen quickstart guides to get started building LPCOpen projects. +[Link: http://www.lpcware.com/content/project/lpcopen-platform-nxp-lpc-microcontrollers/lpcopen-v200-quickstart-guides] + diff --git a/periph_blinky/example/src/cr_startup_lpc15xx.c b/periph_blinky/example/src/cr_startup_lpc15xx.c new file mode 100644 index 0000000..dd9496b --- /dev/null +++ b/periph_blinky/example/src/cr_startup_lpc15xx.c @@ -0,0 +1,505 @@ +//***************************************************************************** +// LPC15xx Microcontroller Startup code for use with LPCXpresso IDE +// +// Version : 150305 +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2014-15 +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// LPC products. This software is supplied "AS IS" without any warranties of +// any kind, and NXP Semiconductors and its licensor disclaim any and +// all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under any +// patent, copyright, mask work right, or any other intellectual property rights in +// or to any products. NXP Semiconductors reserves the right to make changes +// in the software without notification. NXP Semiconductors also makes no +// representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +//***************************************************************************** + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) +// Declaration of external SystemInit function +extern void SystemInit(void); +#endif + +//***************************************************************************** +// +// Forward declaration of the default handlers. These are aliased. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +// +//***************************************************************************** +void ResetISR(void); +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// +// Forward declaration of the specific IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +// +//***************************************************************************** +// Note: The names used for the IRQ Handlers in the LPCXpresso LPC15xx startup +// code did not originally match those used by the LPCOpen LPC15xx packages. +// Now default to using LPCOpen IRQ Handler names. But allow the use of the +// previous names if necessary for legacy code by undefining the below symbol +#define USE_LPCOPEN_IRQHANDLER_NAMES + +#if defined (USE_LPCOPEN_IRQHANDLER_NAMES) +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void FMC_IRQHandler(void) ALIAS(IntDefaultHandler); +void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CAN_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_FIQHandler(void) ALIAS(IntDefaultHandler); +void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0A_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0B_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1A_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1B_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void DAC_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP0_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP1_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP2_IRQHandler(void) ALIAS(IntDefaultHandler); +void ACMP3_IRQHandler(void) ALIAS(IntDefaultHandler); +void QEI_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_ALARM_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_WAKE_IRQHandler(void) ALIAS(IntDefaultHandler); +#else +void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_IRQHandler(void) ALIAS(IntDefaultHandler); +void FLASH_IRQHandler(void) ALIAS(IntDefaultHandler); +void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT4_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT5_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT6_IRQHandler(void) ALIAS(IntDefaultHandler); +void PININT7_IRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT1_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT2_IRQHandler(void) ALIAS(IntDefaultHandler); +void SCT3_IRQHandler(void) ALIAS(IntDefaultHandler); +void MRT_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_IRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_IRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CAN0_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_IRQHandler(void) ALIAS(IntDefaultHandler); +void USB_FIQHandler(void) ALIAS(IntDefaultHandler); +void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_OVR_IRQHandler(void) ALIAS(IntDefaultHandler); +void DAC_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP0_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP1_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP2_IRQHandler(void) ALIAS(IntDefaultHandler); +void CMP3_IRQHandler(void) ALIAS(IntDefaultHandler); +void QEI_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_ALARM_IRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_WAKE_IRQHandler(void) ALIAS(IntDefaultHandler); +#endif +//***************************************************************************** +// +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +// +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); +//***************************************************************************** +// +// External declaration for the pointer to the stack top from the Linker Script +// +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif +//***************************************************************************** +// +// The vector table. +// This relies on the linker script to place at correct location in memory. +// +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +__attribute__ ((used,section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + // Core Level - CM3 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + 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 + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Chip Level - LPC15xx +#if defined (USE_LPCOPEN_IRQHANDLER_NAMES) + WDT_IRQHandler, // 0 - Windowed watchdog timer + BOD_IRQHandler, // 1 - BOD + FMC_IRQHandler, // 2 - Flash controller + EEPROM_IRQHandler, // 3 - EEPROM controller + DMA_IRQHandler, // 4 - DMA + GINT0_IRQHandler, // 5 - GINT0 + GINT1_IRQHandler, // 6 - GINT1 + PIN_INT0_IRQHandler, // 7 - PIO INT0 + PIN_INT1_IRQHandler, // 8 - PIO INT1 + PIN_INT2_IRQHandler, // 9 - PIO INT2 + PIN_INT3_IRQHandler, // 10 - PIO INT3 + PIN_INT4_IRQHandler, // 11 - PIO INT4 + PIN_INT5_IRQHandler, // 12 - PIO INT5 + PIN_INT6_IRQHandler, // 13 - PIO INT6 + PIN_INT7_IRQHandler, // 14 - PIO INT7 + RIT_IRQHandler, // 15 - RIT + SCT0_IRQHandler, // 16 - State configurable timer + SCT1_IRQHandler, // 17 - State configurable timer + SCT2_IRQHandler, // 18 - State configurable timer + SCT3_IRQHandler, // 19 - State configurable timer + MRT_IRQHandler, // 20 - Multi-Rate Timer + UART0_IRQHandler, // 21 - UART0 + UART1_IRQHandler, // 22 - UART1 + UART2_IRQHandler, // 23 - UART2 + I2C0_IRQHandler, // 24 - I2C0 controller + SPI0_IRQHandler, // 25 - SPI0 controller + SPI1_IRQHandler, // 26 - SPI1 controller + CAN_IRQHandler, // 27 - C_CAN0 + USB_IRQHandler, // 28 - USB IRQ + USB_FIQHandler, // 29 - USB FIQ + USBWakeup_IRQHandler, // 30 - USB wake-up + ADC0A_IRQHandler, // 31 - ADC0 sequence A completion + ADC0B_IRQHandler, // 32 - ADC0 sequence B completion + ADC0_THCMP_IRQHandler, // 33 - ADC0 threshold compare + ADC0_OVR_IRQHandler, // 34 - ADC0 overrun + ADC1A_IRQHandler, // 35 - ADC1 sequence A completion + ADC1B_IRQHandler, // 36 - ADC1 sequence B completion + ADC1_THCMP_IRQHandler, // 37 - ADC1 threshold compare + ADC1_OVR_IRQHandler, // 38 - ADC1 overrun + DAC_IRQHandler, // 39 - DAC + ACMP0_IRQHandler, // 40 - Analog Comparator 0 + ACMP1_IRQHandler, // 41 - Analog Comparator 1 + ACMP2_IRQHandler, // 42 - Analog Comparator 2 + ACMP3_IRQHandler, // 43 - Analog Comparator 3 + QEI_IRQHandler, // 44 - QEI + RTC_ALARM_IRQHandler, // 45 - RTC alarm + RTC_WAKE_IRQHandler, // 46 - RTC wake-up +#else + WDT_IRQHandler, // 0 - Windowed watchdog timer + BOD_IRQHandler, // 1 - BOD + FLASH_IRQHandler, // 2 - Flash controller + EEPROM_IRQHandler, // 3 - EEPROM controller + DMA_IRQHandler, // 4 - DMA + GINT0_IRQHandler, // 5 - GINT0 + GINT1_IRQHandler, // 6 - GINT1 + PININT0_IRQHandler, // 7 - PIO INT0 + PININT1_IRQHandler, // 8 - PIO INT1 + PININT2_IRQHandler, // 9 - PIO INT2 + PININT3_IRQHandler, // 10 - PIO INT3 + PININT4_IRQHandler, // 11 - PIO INT4 + PININT5_IRQHandler, // 12 - PIO INT5 + PININT6_IRQHandler, // 13 - PIO INT6 + PININT7_IRQHandler, // 14 - PIO INT7 + RIT_IRQHandler, // 15 - RIT + SCT0_IRQHandler, // 16 - State configurable timer + SCT1_IRQHandler, // 17 - State configurable timer + SCT2_IRQHandler, // 18 - State configurable timer + SCT3_IRQHandler, // 19 - State configurable timer + MRT_IRQHandler, // 20 - Multi-Rate Timer + UART0_IRQHandler, // 21 - UART0 + UART1_IRQHandler, // 22 - UART1 + UART2_IRQHandler, // 23 - UART2 + I2C0_IRQHandler, // 24 - I2C0 controller + SPI0_IRQHandler, // 25 - SPI0 controller + SPI1_IRQHandler, // 26 - SPI1 controller + CAN0_IRQHandler, // 27 - C_CAN0 + USB_IRQHandler, // 28 - USB IRQ + USB_FIQHandler, // 29 - USB FIQ + USBWakeup_IRQHandler, // 30 - USB wake-up + ADC0_SEQA_IRQHandler, // 31 - ADC0 sequence A completion + ADC0_SEQB_IRQHandler, // 32 - ADC0 sequence B completion + ADC0_THCMP_IRQHandler, // 33 - ADC0 threshold compare + ADC0_OVR_IRQHandler, // 34 - ADC0 overrun + ADC1_SEQA_IRQHandler, // 35 - ADC1 sequence A completion + ADC1_SEQB_IRQHandler, // 36 - ADC1 sequence B completion + ADC1_THCMP_IRQHandler, // 37 - ADC1 threshold compare + ADC1_OVR_IRQHandler, // 38 - ADC1 overrun + DAC_IRQHandler, // 39 - DAC + CMP0_IRQHandler, // 40 - Analog Comparator 0 + CMP1_IRQHandler, // 41 - Analog Comparator 1 + CMP2_IRQHandler, // 42 - Analog Comparator 2 + CMP3_IRQHandler, // 43 - Analog Comparator 3 + QEI_IRQHandler, // 44 - QEI + RTC_ALARM_IRQHandler, // 45 - RTC alarm + RTC_WAKE_IRQHandler, // 46 - RTC wake-up +#endif +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void +ResetISR(void) { + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + + // Optionally enable Cortex-M3 SWV trace (off by default at reset) + // Note - your board support must also set up the switch matrix + // so that SWO is output on the appropriate pin for your hardware +#if !defined (DONT_ENABLE_SWVTRACECLK) + // Write 0x00000001 to TRACECLKDIV – Trace divider + volatile unsigned int *TRACECLKDIV = (unsigned int *) 0x400740D8; + *TRACECLKDIV = 1; +#endif + +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) + SystemInit(); +#endif + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main() ; +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void NMI_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void HardFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void MemManage_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void BusFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void UsageFault_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SVC_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void DebugMon_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void PendSV_Handler(void) +{ while(1) {} +} + +__attribute__ ((section(".after_vectors"))) +void SysTick_Handler(void) +{ while(1) {} +} + +//***************************************************************************** +// +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +// +//***************************************************************************** +__attribute__ ((section(".after_vectors"))) +void IntDefaultHandler(void) +{ while(1) {} +} + + + diff --git a/periph_blinky/example/src/sysinit.c b/periph_blinky/example/src/sysinit.c new file mode 100644 index 0000000..e77ffd6 --- /dev/null +++ b/periph_blinky/example/src/sysinit.c @@ -0,0 +1,67 @@ +/* + * @brief Common SystemInit function for LPC15xx chips + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +#if defined(NO_BOARD_LIB) +#include "chip.h" +const uint32_t OscRateIn = 12000000; +const uint32_t RTCOscRateIn = 32768; +#else +#include "board.h" +#endif + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/* Set up and initialize hardware prior to call to main */ +void SystemInit(void) +{ +#if defined(NO_BOARD_LIB) + /* Chip specific SystemInit */ + Chip_SystemInit(); +#else + /* Board specific SystemInit */ + Board_SystemInit(); +#endif +} diff --git a/periph_blinky/example/src/systick.c b/periph_blinky/example/src/systick.c new file mode 100644 index 0000000..704c1f3 --- /dev/null +++ b/periph_blinky/example/src/systick.c @@ -0,0 +1,96 @@ +/* + * @brief Blinky example using timers and sysTick + * + * @note + * Copyright(C) NXP Semiconductors, 2013 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#include "board.h" +#include + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#define TICKRATE_HZ1 (15) /* 15 ticks per second */ + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ + +/***************************************************************************** + * Public functions + ****************************************************************************/ + +/** + * @brief Handle interrupt from SysTick timer + * @return Nothing + */ +void SysTick_Handler(void) +{ + Board_LED_Toggle(0); + Board_LED_Toggle(1); +} + +/** + * @brief main routine for blinky example + * @return Function should not exit. + */ +int main(void) +{ + uint32_t sysTickRate; + + SystemCoreClockUpdate(); + Board_Init(); + Board_LED_Set(0, false); + Board_LED_Set(1, true); + + /* The sysTick counter only has 24 bits of precision, so it will + overflow quickly with a fast core clock. You can alter the + sysTick divider to generate slower sysTick clock rates. */ + Chip_Clock_SetSysTickClockDiv(1); + + /* A SysTick divider is present that scales the sysTick rate down + from the core clock. Using the SystemCoreClock variable as a + rate reference for the SysTick_Config() function won't work, + so get the sysTick rate by calling Chip_Clock_GetSysTickClockRate() */ + sysTickRate = Chip_Clock_GetSysTickClockRate(); + + /* Enable and setup SysTick Timer at a periodic rate */ + SysTick_Config(sysTickRate / TICKRATE_HZ1); + + /* LEDs toggle in interrupt handlers */ + while (1) { + __WFI(); + } + + return 0; +}